1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/i2c.h>
23#include <linux/slab.h>
24#include <linux/types.h>
25#include "../iio.h"
26#include "../sysfs.h"
27#include "magnet.h"
28
29#define HMC5843_I2C_ADDRESS 0x1E
30
31#define HMC5843_CONFIG_REG_A 0x00
32#define HMC5843_CONFIG_REG_B 0x01
33#define HMC5843_MODE_REG 0x02
34#define HMC5843_DATA_OUT_X_MSB_REG 0x03
35#define HMC5843_DATA_OUT_X_LSB_REG 0x04
36#define HMC5843_DATA_OUT_Y_MSB_REG 0x05
37#define HMC5843_DATA_OUT_Y_LSB_REG 0x06
38#define HMC5843_DATA_OUT_Z_MSB_REG 0x07
39#define HMC5843_DATA_OUT_Z_LSB_REG 0x08
40#define HMC5843_STATUS_REG 0x09
41#define HMC5843_ID_REG_A 0x0A
42#define HMC5843_ID_REG_B 0x0B
43#define HMC5843_ID_REG_C 0x0C
44
45#define HMC5843_ID_REG_LENGTH 0x03
46#define HMC5843_ID_STRING "H43"
47
48
49
50
51#define RANGE_GAIN_OFFSET 0x05
52
53#define RANGE_0_7 0x00
54#define RANGE_1_0 0x01
55#define RANGE_1_5 0x02
56#define RANGE_2_0 0x03
57#define RANGE_3_2 0x04
58#define RANGE_3_8 0x05
59#define RANGE_4_5 0x06
60#define RANGE_6_5 0x07
61
62
63
64
65#define DATA_READY 0x01
66#define DATA_OUTPUT_LOCK 0x02
67#define VOLTAGE_REGULATOR_ENABLED 0x04
68
69
70
71
72#define MODE_CONVERSION_CONTINUOUS 0x00
73#define MODE_CONVERSION_SINGLE 0x01
74#define MODE_IDLE 0x02
75#define MODE_SLEEP 0x03
76
77
78#define RATE_OFFSET 0x02
79#define RATE_BITMASK 0x1C
80#define RATE_5 0x00
81#define RATE_10 0x01
82#define RATE_20 0x02
83#define RATE_50 0x03
84#define RATE_100 0x04
85#define RATE_200 0x05
86#define RATE_500 0x06
87#define RATE_NOT_USED 0x07
88
89
90
91
92#define CONF_NORMAL 0x00
93#define CONF_POSITIVE_BIAS 0x01
94#define CONF_NEGATIVE_BIAS 0x02
95#define CONF_NOT_USED 0x03
96#define MEAS_CONF_MASK 0x03
97
98static const char *regval_to_scale[] = {
99 "0.0000006173",
100 "0.0000007692",
101 "0.0000010309",
102 "0.0000012821",
103 "0.0000018868",
104 "0.0000021739",
105 "0.0000025641",
106 "0.0000035714",
107};
108static const int regval_to_input_field_mg[] = {
109 700,
110 1000,
111 1500,
112 2000,
113 3200,
114 3800,
115 4500,
116 6500
117};
118static const char *regval_to_samp_freq[] = {
119 "0.5",
120 "1",
121 "2",
122 "5",
123 "10",
124 "20",
125 "50",
126};
127
128
129static const unsigned short normal_i2c[] = { HMC5843_I2C_ADDRESS,
130 I2C_CLIENT_END };
131
132
133struct hmc5843_data {
134 struct mutex lock;
135 u8 rate;
136 u8 meas_conf;
137 u8 operating_mode;
138 u8 range;
139};
140
141static void hmc5843_init_client(struct i2c_client *client);
142
143static s32 hmc5843_configure(struct i2c_client *client,
144 u8 operating_mode)
145{
146
147 return i2c_smbus_write_byte_data(client,
148 HMC5843_MODE_REG,
149 (operating_mode & 0x03));
150}
151
152
153static ssize_t hmc5843_read_measurement(struct device *dev,
154 struct device_attribute *attr,
155 char *buf)
156{
157 struct iio_dev *indio_dev = dev_get_drvdata(dev);
158 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
159 s16 coordinate_val;
160 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
161 struct hmc5843_data *data = iio_priv(indio_dev);
162 s32 result;
163
164 mutex_lock(&data->lock);
165
166 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
167 while (!(result & DATA_READY))
168 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
169
170 result = i2c_smbus_read_word_data(client, this_attr->address);
171 mutex_unlock(&data->lock);
172 if (result < 0)
173 return -EINVAL;
174
175 coordinate_val = (s16)swab16((u16)result);
176 return sprintf(buf, "%d\n", coordinate_val);
177}
178static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
179 HMC5843_DATA_OUT_X_MSB_REG);
180static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
181 HMC5843_DATA_OUT_Y_MSB_REG);
182static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
183 HMC5843_DATA_OUT_Z_MSB_REG);
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199static ssize_t hmc5843_show_operating_mode(struct device *dev,
200 struct device_attribute *attr,
201 char *buf)
202{
203 struct iio_dev *indio_dev = dev_get_drvdata(dev);
204 struct hmc5843_data *data = iio_priv(indio_dev);
205 return sprintf(buf, "%d\n", data->operating_mode);
206}
207
208static ssize_t hmc5843_set_operating_mode(struct device *dev,
209 struct device_attribute *attr,
210 const char *buf,
211 size_t count)
212{
213 struct iio_dev *indio_dev = dev_get_drvdata(dev);
214 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
215 struct hmc5843_data *data = iio_priv(indio_dev);
216 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
217 unsigned long operating_mode = 0;
218 s32 status;
219 int error;
220 mutex_lock(&data->lock);
221 error = strict_strtoul(buf, 10, &operating_mode);
222 if (error) {
223 count = error;
224 goto exit;
225 }
226 dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
227 if (operating_mode > MODE_SLEEP) {
228 count = -EINVAL;
229 goto exit;
230 }
231
232 status = i2c_smbus_write_byte_data(client, this_attr->address,
233 operating_mode);
234 if (status) {
235 count = -EINVAL;
236 goto exit;
237 }
238 data->operating_mode = operating_mode;
239
240exit:
241 mutex_unlock(&data->lock);
242 return count;
243}
244static IIO_DEVICE_ATTR(operating_mode,
245 S_IWUSR | S_IRUGO,
246 hmc5843_show_operating_mode,
247 hmc5843_set_operating_mode,
248 HMC5843_MODE_REG);
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266static s32 hmc5843_set_meas_conf(struct i2c_client *client,
267 u8 meas_conf)
268{
269 struct hmc5843_data *data = i2c_get_clientdata(client);
270 u8 reg_val;
271 reg_val = (meas_conf & MEAS_CONF_MASK) | (data->rate << RATE_OFFSET);
272 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
273}
274
275static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
276 struct device_attribute *attr,
277 char *buf)
278{
279 struct iio_dev *indio_dev = dev_get_drvdata(dev);
280 struct hmc5843_data *data = iio_priv(indio_dev);
281 return sprintf(buf, "%d\n", data->meas_conf);
282}
283
284static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
285 struct device_attribute *attr,
286 const char *buf,
287 size_t count)
288{
289 struct iio_dev *indio_dev = dev_get_drvdata(dev);
290 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
291 struct hmc5843_data *data = i2c_get_clientdata(client);
292 unsigned long meas_conf = 0;
293 int error = strict_strtoul(buf, 10, &meas_conf);
294 if (error)
295 return error;
296 mutex_lock(&data->lock);
297
298 dev_dbg(dev, "set mode to %lu\n", meas_conf);
299 if (hmc5843_set_meas_conf(client, meas_conf)) {
300 count = -EINVAL;
301 goto exit;
302 }
303 data->meas_conf = meas_conf;
304
305exit:
306 mutex_unlock(&data->lock);
307 return count;
308}
309static IIO_DEVICE_ATTR(meas_conf,
310 S_IWUSR | S_IRUGO,
311 hmc5843_show_measurement_configuration,
312 hmc5843_set_measurement_configuration,
313 0);
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
329
330static s32 hmc5843_set_rate(struct i2c_client *client,
331 u8 rate)
332{
333 struct hmc5843_data *data = i2c_get_clientdata(client);
334 u8 reg_val;
335
336 reg_val = (data->meas_conf) | (rate << RATE_OFFSET);
337 if (rate >= RATE_NOT_USED) {
338 dev_err(&client->dev,
339 "This data output rate is not supported \n");
340 return -EINVAL;
341 }
342 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
343}
344
345static ssize_t set_sampling_frequency(struct device *dev,
346 struct device_attribute *attr,
347 const char *buf, size_t count)
348{
349
350 struct iio_dev *indio_dev = dev_get_drvdata(dev);
351 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
352 struct hmc5843_data *data = iio_priv(indio_dev);
353 unsigned long rate = 0;
354
355 if (strncmp(buf, "0.5" , 3) == 0)
356 rate = RATE_5;
357 else if (strncmp(buf, "1" , 1) == 0)
358 rate = RATE_10;
359 else if (strncmp(buf, "2", 1) == 0)
360 rate = RATE_20;
361 else if (strncmp(buf, "5", 1) == 0)
362 rate = RATE_50;
363 else if (strncmp(buf, "10", 2) == 0)
364 rate = RATE_100;
365 else if (strncmp(buf, "20" , 2) == 0)
366 rate = RATE_200;
367 else if (strncmp(buf, "50" , 2) == 0)
368 rate = RATE_500;
369 else
370 return -EINVAL;
371
372 mutex_lock(&data->lock);
373 dev_dbg(dev, "set rate to %lu\n", rate);
374 if (hmc5843_set_rate(client, rate)) {
375 count = -EINVAL;
376 goto exit;
377 }
378 data->rate = rate;
379
380exit:
381 mutex_unlock(&data->lock);
382 return count;
383}
384
385static ssize_t show_sampling_frequency(struct device *dev,
386 struct device_attribute *attr, char *buf)
387{
388 struct iio_dev *indio_dev = dev_get_drvdata(dev);
389 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
390 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
391 s32 rate;
392
393 rate = i2c_smbus_read_byte_data(client, this_attr->address);
394 if (rate < 0)
395 return rate;
396 rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
397 return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
398}
399static IIO_DEVICE_ATTR(sampling_frequency,
400 S_IWUSR | S_IRUGO,
401 show_sampling_frequency,
402 set_sampling_frequency,
403 HMC5843_CONFIG_REG_A);
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418static ssize_t show_range(struct device *dev,
419 struct device_attribute *attr,
420 char *buf)
421{
422 u8 range;
423 struct iio_dev *indio_dev = dev_get_drvdata(dev);
424 struct hmc5843_data *data = iio_priv(indio_dev);
425
426 range = data->range;
427 return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
428}
429
430static ssize_t set_range(struct device *dev,
431 struct device_attribute *attr,
432 const char *buf,
433 size_t count)
434{
435 struct iio_dev *indio_dev = dev_get_drvdata(dev);
436 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
437 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
438 struct hmc5843_data *data = iio_priv(indio_dev);
439 unsigned long range = 0;
440 int error;
441 mutex_lock(&data->lock);
442 error = strict_strtoul(buf, 10, &range);
443 if (error) {
444 count = error;
445 goto exit;
446 }
447 dev_dbg(dev, "set range to %lu\n", range);
448
449 if (range > RANGE_6_5) {
450 count = -EINVAL;
451 goto exit;
452 }
453
454 data->range = range;
455 range = range << RANGE_GAIN_OFFSET;
456 if (i2c_smbus_write_byte_data(client, this_attr->address, range))
457 count = -EINVAL;
458
459exit:
460 mutex_unlock(&data->lock);
461 return count;
462
463}
464static IIO_DEVICE_ATTR(magn_range,
465 S_IWUSR | S_IRUGO,
466 show_range,
467 set_range,
468 HMC5843_CONFIG_REG_B);
469
470static ssize_t show_scale(struct device *dev,
471 struct device_attribute *attr,
472 char *buf)
473{
474 struct iio_dev *indio_dev = dev_get_drvdata(dev);
475 struct hmc5843_data *data = iio_priv(indio_dev);
476 return strlen(strcpy(buf, regval_to_scale[data->range]));
477}
478static IIO_DEVICE_ATTR(magn_scale,
479 S_IRUGO,
480 show_scale,
481 NULL , 0);
482
483static struct attribute *hmc5843_attributes[] = {
484 &iio_dev_attr_meas_conf.dev_attr.attr,
485 &iio_dev_attr_operating_mode.dev_attr.attr,
486 &iio_dev_attr_sampling_frequency.dev_attr.attr,
487 &iio_dev_attr_magn_range.dev_attr.attr,
488 &iio_dev_attr_magn_scale.dev_attr.attr,
489 &iio_dev_attr_magn_x_raw.dev_attr.attr,
490 &iio_dev_attr_magn_y_raw.dev_attr.attr,
491 &iio_dev_attr_magn_z_raw.dev_attr.attr,
492 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
493 NULL
494};
495
496static const struct attribute_group hmc5843_group = {
497 .attrs = hmc5843_attributes,
498};
499
500static int hmc5843_detect(struct i2c_client *client,
501 struct i2c_board_info *info)
502{
503 unsigned char id_str[HMC5843_ID_REG_LENGTH];
504
505 if (client->addr != HMC5843_I2C_ADDRESS)
506 return -ENODEV;
507
508 if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
509 HMC5843_ID_REG_LENGTH, id_str)
510 != HMC5843_ID_REG_LENGTH)
511 return -ENODEV;
512
513 if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
514 return -ENODEV;
515
516 return 0;
517}
518
519
520static void hmc5843_init_client(struct i2c_client *client)
521{
522 struct hmc5843_data *data = i2c_get_clientdata(client);
523 hmc5843_set_meas_conf(client, data->meas_conf);
524 hmc5843_set_rate(client, data->rate);
525 hmc5843_configure(client, data->operating_mode);
526 i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
527 mutex_init(&data->lock);
528 pr_info("HMC5843 initialized\n");
529}
530
531static const struct iio_info hmc5843_info = {
532 .attrs = &hmc5843_group,
533 .driver_module = THIS_MODULE,
534};
535
536static int hmc5843_probe(struct i2c_client *client,
537 const struct i2c_device_id *id)
538{
539 struct hmc5843_data *data;
540 struct iio_dev *indio_dev;
541 int err = 0;
542
543 indio_dev = iio_allocate_device(sizeof(*data));
544 if (indio_dev == NULL) {
545 err = -ENOMEM;
546 goto exit;
547 }
548 data = iio_priv(indio_dev);
549
550
551 data->meas_conf = CONF_NORMAL;
552 data->range = RANGE_1_0;
553 data->operating_mode = MODE_CONVERSION_CONTINUOUS;
554
555 i2c_set_clientdata(client, indio_dev);
556
557
558 hmc5843_init_client(client);
559
560 indio_dev->info = &hmc5843_info;
561 indio_dev->dev.parent = &client->dev;
562 indio_dev->modes = INDIO_DIRECT_MODE;
563 err = iio_device_register(indio_dev);
564 if (err)
565 goto exit_free2;
566 return 0;
567exit_free2:
568 iio_free_device(indio_dev);
569exit:
570 return err;
571}
572
573static int hmc5843_remove(struct i2c_client *client)
574{
575 struct iio_dev *indio_dev = i2c_get_clientdata(client);
576
577 hmc5843_configure(client, MODE_SLEEP);
578 iio_device_unregister(indio_dev);
579
580 return 0;
581}
582
583static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
584{
585 hmc5843_configure(client, MODE_SLEEP);
586 return 0;
587}
588
589static int hmc5843_resume(struct i2c_client *client)
590{
591 struct hmc5843_data *data = i2c_get_clientdata(client);
592 hmc5843_configure(client, data->operating_mode);
593 return 0;
594}
595
596static const struct i2c_device_id hmc5843_id[] = {
597 { "hmc5843", 0 },
598 { }
599};
600
601static struct i2c_driver hmc5843_driver = {
602 .driver = {
603 .name = "hmc5843",
604 },
605 .id_table = hmc5843_id,
606 .probe = hmc5843_probe,
607 .remove = hmc5843_remove,
608 .detect = hmc5843_detect,
609 .address_list = normal_i2c,
610 .suspend = hmc5843_suspend,
611 .resume = hmc5843_resume,
612};
613
614static int __init hmc5843_init(void)
615{
616 return i2c_add_driver(&hmc5843_driver);
617}
618
619static void __exit hmc5843_exit(void)
620{
621 i2c_del_driver(&hmc5843_driver);
622}
623
624MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
625MODULE_DESCRIPTION("HMC5843 driver");
626MODULE_LICENSE("GPL");
627
628module_init(hmc5843_init);
629module_exit(hmc5843_exit);
630