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 iio_dev *indio_dev;
135 struct mutex lock;
136 u8 rate;
137 u8 meas_conf;
138 u8 operating_mode;
139 u8 range;
140};
141
142static void hmc5843_init_client(struct i2c_client *client);
143
144static s32 hmc5843_configure(struct i2c_client *client,
145 u8 operating_mode)
146{
147
148 return i2c_smbus_write_byte_data(client,
149 HMC5843_MODE_REG,
150 (operating_mode & 0x03));
151}
152
153
154static ssize_t hmc5843_read_measurement(struct device *dev,
155 struct device_attribute *attr,
156 char *buf)
157{
158 struct iio_dev *indio_dev = dev_get_drvdata(dev);
159 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
160 s16 coordinate_val;
161 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
162 struct hmc5843_data *data = indio_dev->dev_data;
163 s32 result;
164
165 mutex_lock(&data->lock);
166
167 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
168 while (!(result & DATA_READY))
169 result = i2c_smbus_read_byte_data(client, HMC5843_STATUS_REG);
170
171 result = i2c_smbus_read_word_data(client, this_attr->address);
172 mutex_unlock(&data->lock);
173 if (result < 0)
174 return -EINVAL;
175
176 coordinate_val = (s16)swab16((u16)result);
177 return sprintf(buf, "%d\n", coordinate_val);
178}
179static IIO_DEV_ATTR_MAGN_X(hmc5843_read_measurement,
180 HMC5843_DATA_OUT_X_MSB_REG);
181static IIO_DEV_ATTR_MAGN_Y(hmc5843_read_measurement,
182 HMC5843_DATA_OUT_Y_MSB_REG);
183static IIO_DEV_ATTR_MAGN_Z(hmc5843_read_measurement,
184 HMC5843_DATA_OUT_Z_MSB_REG);
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200static ssize_t hmc5843_show_operating_mode(struct device *dev,
201 struct device_attribute *attr,
202 char *buf)
203{
204 struct iio_dev *indio_dev = dev_get_drvdata(dev);
205 struct hmc5843_data *data = indio_dev->dev_data;
206 return sprintf(buf, "%d\n", data->operating_mode);
207}
208
209static ssize_t hmc5843_set_operating_mode(struct device *dev,
210 struct device_attribute *attr,
211 const char *buf,
212 size_t count)
213{
214 struct iio_dev *indio_dev = dev_get_drvdata(dev);
215 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
216 struct hmc5843_data *data = indio_dev->dev_data;
217 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
218 unsigned long operating_mode = 0;
219 s32 status;
220 int error;
221 mutex_lock(&data->lock);
222 error = strict_strtoul(buf, 10, &operating_mode);
223 if (error) {
224 count = error;
225 goto exit;
226 }
227 dev_dbg(dev, "set Conversion mode to %lu\n", operating_mode);
228 if (operating_mode > MODE_SLEEP) {
229 count = -EINVAL;
230 goto exit;
231 }
232
233 status = i2c_smbus_write_byte_data(client, this_attr->address,
234 operating_mode);
235 if (status) {
236 count = -EINVAL;
237 goto exit;
238 }
239 data->operating_mode = operating_mode;
240
241exit:
242 mutex_unlock(&data->lock);
243 return count;
244}
245static IIO_DEVICE_ATTR(operating_mode,
246 S_IWUSR | S_IRUGO,
247 hmc5843_show_operating_mode,
248 hmc5843_set_operating_mode,
249 HMC5843_MODE_REG);
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267static s32 hmc5843_set_meas_conf(struct i2c_client *client,
268 u8 meas_conf)
269{
270 struct hmc5843_data *data = i2c_get_clientdata(client);
271 u8 reg_val;
272 reg_val = (meas_conf & MEAS_CONF_MASK) | (data->rate << RATE_OFFSET);
273 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
274}
275
276static ssize_t hmc5843_show_measurement_configuration(struct device *dev,
277 struct device_attribute *attr,
278 char *buf)
279{
280 struct iio_dev *indio_dev = dev_get_drvdata(dev);
281 struct hmc5843_data *data = indio_dev->dev_data;
282 return sprintf(buf, "%d\n", data->meas_conf);
283}
284
285static ssize_t hmc5843_set_measurement_configuration(struct device *dev,
286 struct device_attribute *attr,
287 const char *buf,
288 size_t count)
289{
290 struct iio_dev *indio_dev = dev_get_drvdata(dev);
291 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
292 struct hmc5843_data *data = i2c_get_clientdata(client);
293 unsigned long meas_conf = 0;
294 int error = strict_strtoul(buf, 10, &meas_conf);
295 if (error)
296 return error;
297 mutex_lock(&data->lock);
298
299 dev_dbg(dev, "set mode to %lu\n", meas_conf);
300 if (hmc5843_set_meas_conf(client, meas_conf)) {
301 count = -EINVAL;
302 goto exit;
303 }
304 data->meas_conf = meas_conf;
305
306exit:
307 mutex_unlock(&data->lock);
308 return count;
309}
310static IIO_DEVICE_ATTR(meas_conf,
311 S_IWUSR | S_IRUGO,
312 hmc5843_show_measurement_configuration,
313 hmc5843_set_measurement_configuration,
314 0);
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.5 1 2 5 10 20 50");
330
331static s32 hmc5843_set_rate(struct i2c_client *client,
332 u8 rate)
333{
334 struct hmc5843_data *data = i2c_get_clientdata(client);
335 u8 reg_val;
336
337 reg_val = (data->meas_conf) | (rate << RATE_OFFSET);
338 if (rate >= RATE_NOT_USED) {
339 dev_err(&client->dev,
340 "This data output rate is not supported \n");
341 return -EINVAL;
342 }
343 return i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_A, reg_val);
344}
345
346static ssize_t set_sampling_frequency(struct device *dev,
347 struct device_attribute *attr,
348 const char *buf, size_t count)
349{
350
351 struct iio_dev *indio_dev = dev_get_drvdata(dev);
352 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
353 struct hmc5843_data *data = indio_dev->dev_data;
354 unsigned long rate = 0;
355
356 if (strncmp(buf, "0.5" , 3) == 0)
357 rate = RATE_5;
358 else if (strncmp(buf, "1" , 1) == 0)
359 rate = RATE_10;
360 else if (strncmp(buf, "2", 1) == 0)
361 rate = RATE_20;
362 else if (strncmp(buf, "5", 1) == 0)
363 rate = RATE_50;
364 else if (strncmp(buf, "10", 2) == 0)
365 rate = RATE_100;
366 else if (strncmp(buf, "20" , 2) == 0)
367 rate = RATE_200;
368 else if (strncmp(buf, "50" , 2) == 0)
369 rate = RATE_500;
370 else
371 return -EINVAL;
372
373 mutex_lock(&data->lock);
374 dev_dbg(dev, "set rate to %lu\n", rate);
375 if (hmc5843_set_rate(client, rate)) {
376 count = -EINVAL;
377 goto exit;
378 }
379 data->rate = rate;
380
381exit:
382 mutex_unlock(&data->lock);
383 return count;
384}
385
386static ssize_t show_sampling_frequency(struct device *dev,
387 struct device_attribute *attr, char *buf)
388{
389 struct iio_dev *indio_dev = dev_get_drvdata(dev);
390 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
391 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
392 s32 rate;
393
394 rate = i2c_smbus_read_byte_data(client, this_attr->address);
395 if (rate < 0)
396 return rate;
397 rate = (rate & RATE_BITMASK) >> RATE_OFFSET;
398 return sprintf(buf, "%s\n", regval_to_samp_freq[rate]);
399}
400static IIO_DEVICE_ATTR(sampling_frequency,
401 S_IWUSR | S_IRUGO,
402 show_sampling_frequency,
403 set_sampling_frequency,
404 HMC5843_CONFIG_REG_A);
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419static ssize_t show_range(struct device *dev,
420 struct device_attribute *attr,
421 char *buf)
422{
423 u8 range;
424 struct iio_dev *indio_dev = dev_get_drvdata(dev);
425 struct hmc5843_data *data = indio_dev->dev_data;
426
427 range = data->range;
428 return sprintf(buf, "%d\n", regval_to_input_field_mg[range]);
429}
430
431static ssize_t set_range(struct device *dev,
432 struct device_attribute *attr,
433 const char *buf,
434 size_t count)
435{
436 struct iio_dev *indio_dev = dev_get_drvdata(dev);
437 struct i2c_client *client = to_i2c_client(indio_dev->dev.parent);
438 struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
439 struct hmc5843_data *data = indio_dev->dev_data;
440 unsigned long range = 0;
441 int error;
442 mutex_lock(&data->lock);
443 error = strict_strtoul(buf, 10, &range);
444 if (error) {
445 count = error;
446 goto exit;
447 }
448 dev_dbg(dev, "set range to %lu\n", range);
449
450 if (range > RANGE_6_5) {
451 count = -EINVAL;
452 goto exit;
453 }
454
455 data->range = range;
456 range = range << RANGE_GAIN_OFFSET;
457 if (i2c_smbus_write_byte_data(client, this_attr->address, range))
458 count = -EINVAL;
459
460exit:
461 mutex_unlock(&data->lock);
462 return count;
463
464}
465static IIO_DEVICE_ATTR(magn_range,
466 S_IWUSR | S_IRUGO,
467 show_range,
468 set_range,
469 HMC5843_CONFIG_REG_B);
470
471static ssize_t show_scale(struct device *dev,
472 struct device_attribute *attr,
473 char *buf)
474{
475 struct iio_dev *indio_dev = dev_get_drvdata(dev);
476 struct hmc5843_data *data = indio_dev->dev_data;
477 return strlen(strcpy(buf, regval_to_scale[data->range]));
478}
479static IIO_DEVICE_ATTR(magn_scale,
480 S_IRUGO,
481 show_scale,
482 NULL , 0);
483
484static struct attribute *hmc5843_attributes[] = {
485 &iio_dev_attr_meas_conf.dev_attr.attr,
486 &iio_dev_attr_operating_mode.dev_attr.attr,
487 &iio_dev_attr_sampling_frequency.dev_attr.attr,
488 &iio_dev_attr_magn_range.dev_attr.attr,
489 &iio_dev_attr_magn_scale.dev_attr.attr,
490 &iio_dev_attr_magn_x_raw.dev_attr.attr,
491 &iio_dev_attr_magn_y_raw.dev_attr.attr,
492 &iio_dev_attr_magn_z_raw.dev_attr.attr,
493 &iio_const_attr_sampling_frequency_available.dev_attr.attr,
494 NULL
495};
496
497static const struct attribute_group hmc5843_group = {
498 .attrs = hmc5843_attributes,
499};
500
501static int hmc5843_detect(struct i2c_client *client,
502 struct i2c_board_info *info)
503{
504 unsigned char id_str[HMC5843_ID_REG_LENGTH];
505
506 if (client->addr != HMC5843_I2C_ADDRESS)
507 return -ENODEV;
508
509 if (i2c_smbus_read_i2c_block_data(client, HMC5843_ID_REG_A,
510 HMC5843_ID_REG_LENGTH, id_str)
511 != HMC5843_ID_REG_LENGTH)
512 return -ENODEV;
513
514 if (0 != strncmp(id_str, HMC5843_ID_STRING, HMC5843_ID_REG_LENGTH))
515 return -ENODEV;
516
517 return 0;
518}
519
520
521static void hmc5843_init_client(struct i2c_client *client)
522{
523 struct hmc5843_data *data = i2c_get_clientdata(client);
524 hmc5843_set_meas_conf(client, data->meas_conf);
525 hmc5843_set_rate(client, data->rate);
526 hmc5843_configure(client, data->operating_mode);
527 i2c_smbus_write_byte_data(client, HMC5843_CONFIG_REG_B, data->range);
528 mutex_init(&data->lock);
529 pr_info("HMC5843 initialized\n");
530}
531
532static int hmc5843_probe(struct i2c_client *client,
533 const struct i2c_device_id *id)
534{
535 struct hmc5843_data *data;
536 int err = 0;
537
538 data = kzalloc(sizeof(struct hmc5843_data), GFP_KERNEL);
539 if (!data) {
540 err = -ENOMEM;
541 goto exit;
542 }
543
544
545
546 data->meas_conf = CONF_NORMAL;
547 data->range = RANGE_1_0;
548 data->operating_mode = MODE_CONVERSION_CONTINUOUS;
549
550 i2c_set_clientdata(client, data);
551
552
553 hmc5843_init_client(client);
554
555 data->indio_dev = iio_allocate_device();
556 if (!data->indio_dev) {
557 err = -ENOMEM;
558 goto exit_free1;
559 }
560 data->indio_dev->attrs = &hmc5843_group;
561 data->indio_dev->dev.parent = &client->dev;
562 data->indio_dev->dev_data = (void *)(data);
563 data->indio_dev->driver_module = THIS_MODULE;
564 data->indio_dev->modes = INDIO_DIRECT_MODE;
565 err = iio_device_register(data->indio_dev);
566 if (err)
567 goto exit_free2;
568 return 0;
569exit_free2:
570 iio_free_device(data->indio_dev);
571exit_free1:
572 kfree(data);
573exit:
574 return err;
575}
576
577static int hmc5843_remove(struct i2c_client *client)
578{
579 struct hmc5843_data *data = i2c_get_clientdata(client);
580
581 hmc5843_configure(client, MODE_SLEEP);
582 iio_device_unregister(data->indio_dev);
583 kfree(i2c_get_clientdata(client));
584 return 0;
585}
586
587static int hmc5843_suspend(struct i2c_client *client, pm_message_t mesg)
588{
589 hmc5843_configure(client, MODE_SLEEP);
590 return 0;
591}
592
593static int hmc5843_resume(struct i2c_client *client)
594{
595 struct hmc5843_data *data = i2c_get_clientdata(client);
596 hmc5843_configure(client, data->operating_mode);
597 return 0;
598}
599
600static const struct i2c_device_id hmc5843_id[] = {
601 { "hmc5843", 0 },
602 { }
603};
604
605static struct i2c_driver hmc5843_driver = {
606 .driver = {
607 .name = "hmc5843",
608 },
609 .id_table = hmc5843_id,
610 .probe = hmc5843_probe,
611 .remove = hmc5843_remove,
612 .detect = hmc5843_detect,
613 .address_list = normal_i2c,
614 .suspend = hmc5843_suspend,
615 .resume = hmc5843_resume,
616};
617
618static int __init hmc5843_init(void)
619{
620 return i2c_add_driver(&hmc5843_driver);
621}
622
623static void __exit hmc5843_exit(void)
624{
625 i2c_del_driver(&hmc5843_driver);
626}
627
628MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
629MODULE_DESCRIPTION("HMC5843 driver");
630MODULE_LICENSE("GPL");
631
632module_init(hmc5843_init);
633module_exit(hmc5843_exit);
634