Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lm3533-core.c
Go to the documentation of this file.
1 /*
2  * lm3533-core.c -- LM3533 Core
3  *
4  * Copyright (C) 2011-2012 Texas Instruments
5  *
6  * Author: Johan Hovold <[email protected]>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms of the GNU General Public License as published by the
10  * Free Software Foundation; either version 2 of the License, or (at your
11  * option) any later version.
12  */
13 
14 #include <linux/module.h>
15 #include <linux/init.h>
16 #include <linux/kernel.h>
17 #include <linux/err.h>
18 #include <linux/gpio.h>
19 #include <linux/i2c.h>
20 #include <linux/mfd/core.h>
21 #include <linux/regmap.h>
22 #include <linux/seq_file.h>
23 #include <linux/slab.h>
24 #include <linux/uaccess.h>
25 
26 #include <linux/mfd/lm3533.h>
27 
28 
29 #define LM3533_BOOST_OVP_MASK 0x06
30 #define LM3533_BOOST_OVP_SHIFT 1
31 
32 #define LM3533_BOOST_FREQ_MASK 0x01
33 #define LM3533_BOOST_FREQ_SHIFT 0
34 
35 #define LM3533_BL_ID_MASK 1
36 #define LM3533_LED_ID_MASK 3
37 #define LM3533_BL_ID_MAX 1
38 #define LM3533_LED_ID_MAX 3
39 
40 #define LM3533_HVLED_ID_MAX 2
41 #define LM3533_LVLED_ID_MAX 5
42 
43 #define LM3533_REG_OUTPUT_CONF1 0x10
44 #define LM3533_REG_OUTPUT_CONF2 0x11
45 #define LM3533_REG_BOOST_PWM 0x2c
46 
47 #define LM3533_REG_MAX 0xb2
48 
49 
50 static struct mfd_cell lm3533_als_devs[] = {
51  {
52  .name = "lm3533-als",
53  .id = -1,
54  },
55 };
56 
57 static struct mfd_cell lm3533_bl_devs[] = {
58  {
59  .name = "lm3533-backlight",
60  .id = 0,
61  },
62  {
63  .name = "lm3533-backlight",
64  .id = 1,
65  },
66 };
67 
68 static struct mfd_cell lm3533_led_devs[] = {
69  {
70  .name = "lm3533-leds",
71  .id = 0,
72  },
73  {
74  .name = "lm3533-leds",
75  .id = 1,
76  },
77  {
78  .name = "lm3533-leds",
79  .id = 2,
80  },
81  {
82  .name = "lm3533-leds",
83  .id = 3,
84  },
85 };
86 
87 int lm3533_read(struct lm3533 *lm3533, u8 reg, u8 *val)
88 {
89  int tmp;
90  int ret;
91 
92  ret = regmap_read(lm3533->regmap, reg, &tmp);
93  if (ret < 0) {
94  dev_err(lm3533->dev, "failed to read register %02x: %d\n",
95  reg, ret);
96  return ret;
97  }
98 
99  *val = tmp;
100 
101  dev_dbg(lm3533->dev, "read [%02x]: %02x\n", reg, *val);
102 
103  return ret;
104 }
106 
108 {
109  int ret;
110 
111  dev_dbg(lm3533->dev, "write [%02x]: %02x\n", reg, val);
112 
113  ret = regmap_write(lm3533->regmap, reg, val);
114  if (ret < 0) {
115  dev_err(lm3533->dev, "failed to write register %02x: %d\n",
116  reg, ret);
117  }
118 
119  return ret;
120 }
122 
124 {
125  int ret;
126 
127  dev_dbg(lm3533->dev, "update [%02x]: %02x/%02x\n", reg, val, mask);
128 
129  ret = regmap_update_bits(lm3533->regmap, reg, mask, val);
130  if (ret < 0) {
131  dev_err(lm3533->dev, "failed to update register %02x: %d\n",
132  reg, ret);
133  }
134 
135  return ret;
136 }
138 
139 static int lm3533_set_boost_freq(struct lm3533 *lm3533,
140  enum lm3533_boost_freq freq)
141 {
142  int ret;
143 
144  ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM,
145  freq << LM3533_BOOST_FREQ_SHIFT,
147  if (ret)
148  dev_err(lm3533->dev, "failed to set boost frequency\n");
149 
150  return ret;
151 }
152 
153 
154 static int lm3533_set_boost_ovp(struct lm3533 *lm3533,
155  enum lm3533_boost_ovp ovp)
156 {
157  int ret;
158 
159  ret = lm3533_update(lm3533, LM3533_REG_BOOST_PWM,
160  ovp << LM3533_BOOST_OVP_SHIFT,
162  if (ret)
163  dev_err(lm3533->dev, "failed to set boost ovp\n");
164 
165  return ret;
166 }
167 
168 /*
169  * HVLED output config -- output hvled controlled by backlight bl
170  */
171 static int lm3533_set_hvled_config(struct lm3533 *lm3533, u8 hvled, u8 bl)
172 {
173  u8 val;
174  u8 mask;
175  int shift;
176  int ret;
177 
178  if (hvled == 0 || hvled > LM3533_HVLED_ID_MAX)
179  return -EINVAL;
180 
181  if (bl > LM3533_BL_ID_MAX)
182  return -EINVAL;
183 
184  shift = hvled - 1;
185  mask = LM3533_BL_ID_MASK << shift;
186  val = bl << shift;
187 
188  ret = lm3533_update(lm3533, LM3533_REG_OUTPUT_CONF1, val, mask);
189  if (ret)
190  dev_err(lm3533->dev, "failed to set hvled config\n");
191 
192  return ret;
193 }
194 
195 /*
196  * LVLED output config -- output lvled controlled by LED led
197  */
198 static int lm3533_set_lvled_config(struct lm3533 *lm3533, u8 lvled, u8 led)
199 {
200  u8 reg;
201  u8 val;
202  u8 mask;
203  int shift;
204  int ret;
205 
206  if (lvled == 0 || lvled > LM3533_LVLED_ID_MAX)
207  return -EINVAL;
208 
209  if (led > LM3533_LED_ID_MAX)
210  return -EINVAL;
211 
212  if (lvled < 4) {
214  shift = 2 * lvled;
215  } else {
217  shift = 2 * (lvled - 4);
218  }
219 
220  mask = LM3533_LED_ID_MASK << shift;
221  val = led << shift;
222 
223  ret = lm3533_update(lm3533, reg, val, mask);
224  if (ret)
225  dev_err(lm3533->dev, "failed to set lvled config\n");
226 
227  return ret;
228 }
229 
230 static void lm3533_enable(struct lm3533 *lm3533)
231 {
232  if (gpio_is_valid(lm3533->gpio_hwen))
233  gpio_set_value(lm3533->gpio_hwen, 1);
234 }
235 
236 static void lm3533_disable(struct lm3533 *lm3533)
237 {
238  if (gpio_is_valid(lm3533->gpio_hwen))
239  gpio_set_value(lm3533->gpio_hwen, 0);
240 }
241 
245 };
246 
250  union {
251  struct {
253  } output;
254  } u;
255 };
256 
257 #define to_lm3533_dev_attr(_attr) \
258  container_of(_attr, struct lm3533_device_attribute, dev_attr)
259 
260 static ssize_t show_output(struct device *dev,
261  struct device_attribute *attr, char *buf)
262 {
263  struct lm3533 *lm3533 = dev_get_drvdata(dev);
264  struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr);
265  int id = lattr->u.output.id;
266  u8 reg;
267  u8 val;
268  u8 mask;
269  int shift;
270  int ret;
271 
272  if (lattr->type == LM3533_ATTR_TYPE_BACKLIGHT) {
274  shift = id - 1;
275  mask = LM3533_BL_ID_MASK << shift;
276  } else {
277  if (id < 4) {
279  shift = 2 * id;
280  } else {
282  shift = 2 * (id - 4);
283  }
284  mask = LM3533_LED_ID_MASK << shift;
285  }
286 
287  ret = lm3533_read(lm3533, reg, &val);
288  if (ret)
289  return ret;
290 
291  val = (val & mask) >> shift;
292 
293  return scnprintf(buf, PAGE_SIZE, "%u\n", val);
294 }
295 
296 static ssize_t store_output(struct device *dev,
297  struct device_attribute *attr,
298  const char *buf, size_t len)
299 {
300  struct lm3533 *lm3533 = dev_get_drvdata(dev);
301  struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(attr);
302  int id = lattr->u.output.id;
303  u8 val;
304  int ret;
305 
306  if (kstrtou8(buf, 0, &val))
307  return -EINVAL;
308 
309  if (lattr->type == LM3533_ATTR_TYPE_BACKLIGHT)
310  ret = lm3533_set_hvled_config(lm3533, id, val);
311  else
312  ret = lm3533_set_lvled_config(lm3533, id, val);
313 
314  if (ret)
315  return ret;
316 
317  return len;
318 }
319 
320 #define LM3533_OUTPUT_ATTR(_name, _mode, _show, _store, _type, _id) \
321  struct lm3533_device_attribute lm3533_dev_attr_##_name = \
322  { .dev_attr = __ATTR(_name, _mode, _show, _store), \
323  .type = _type, \
324  .u.output = { .id = _id }, }
325 
326 #define LM3533_OUTPUT_ATTR_RW(_name, _type, _id) \
327  LM3533_OUTPUT_ATTR(output_##_name, S_IRUGO | S_IWUSR, \
328  show_output, store_output, _type, _id)
329 
330 #define LM3533_OUTPUT_HVLED_ATTR_RW(_nr) \
331  LM3533_OUTPUT_ATTR_RW(hvled##_nr, LM3533_ATTR_TYPE_BACKLIGHT, _nr)
332 #define LM3533_OUTPUT_LVLED_ATTR_RW(_nr) \
333  LM3533_OUTPUT_ATTR_RW(lvled##_nr, LM3533_ATTR_TYPE_LED, _nr)
334 /*
335  * Output config:
336  *
337  * output_hvled<nr> 0-1
338  * output_lvled<nr> 0-3
339  */
347 
348 static struct attribute *lm3533_attributes[] = {
349  &lm3533_dev_attr_output_hvled1.dev_attr.attr,
350  &lm3533_dev_attr_output_hvled2.dev_attr.attr,
351  &lm3533_dev_attr_output_lvled1.dev_attr.attr,
352  &lm3533_dev_attr_output_lvled2.dev_attr.attr,
353  &lm3533_dev_attr_output_lvled3.dev_attr.attr,
354  &lm3533_dev_attr_output_lvled4.dev_attr.attr,
355  &lm3533_dev_attr_output_lvled5.dev_attr.attr,
356  NULL,
357 };
358 
359 #define to_dev_attr(_attr) \
360  container_of(_attr, struct device_attribute, attr)
361 
362 static umode_t lm3533_attr_is_visible(struct kobject *kobj,
363  struct attribute *attr, int n)
364 {
365  struct device *dev = container_of(kobj, struct device, kobj);
366  struct lm3533 *lm3533 = dev_get_drvdata(dev);
367  struct device_attribute *dattr = to_dev_attr(attr);
368  struct lm3533_device_attribute *lattr = to_lm3533_dev_attr(dattr);
369  enum lm3533_attribute_type type = lattr->type;
370  umode_t mode = attr->mode;
371 
372  if (!lm3533->have_backlights && type == LM3533_ATTR_TYPE_BACKLIGHT)
373  mode = 0;
374  else if (!lm3533->have_leds && type == LM3533_ATTR_TYPE_LED)
375  mode = 0;
376 
377  return mode;
378 };
379 
380 static struct attribute_group lm3533_attribute_group = {
381  .is_visible = lm3533_attr_is_visible,
382  .attrs = lm3533_attributes
383 };
384 
385 static int __devinit lm3533_device_als_init(struct lm3533 *lm3533)
386 {
387  struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
388  int ret;
389 
390  if (!pdata->als)
391  return 0;
392 
393  lm3533_als_devs[0].platform_data = pdata->als;
394  lm3533_als_devs[0].pdata_size = sizeof(*pdata->als);
395 
396  ret = mfd_add_devices(lm3533->dev, 0, lm3533_als_devs, 1, NULL,
397  0, NULL);
398  if (ret) {
399  dev_err(lm3533->dev, "failed to add ALS device\n");
400  return ret;
401  }
402 
403  lm3533->have_als = 1;
404 
405  return 0;
406 }
407 
408 static int __devinit lm3533_device_bl_init(struct lm3533 *lm3533)
409 {
410  struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
411  int i;
412  int ret;
413 
414  if (!pdata->backlights || pdata->num_backlights == 0)
415  return 0;
416 
417  if (pdata->num_backlights > ARRAY_SIZE(lm3533_bl_devs))
418  pdata->num_backlights = ARRAY_SIZE(lm3533_bl_devs);
419 
420  for (i = 0; i < pdata->num_backlights; ++i) {
421  lm3533_bl_devs[i].platform_data = &pdata->backlights[i];
422  lm3533_bl_devs[i].pdata_size = sizeof(pdata->backlights[i]);
423  }
424 
425  ret = mfd_add_devices(lm3533->dev, 0, lm3533_bl_devs,
426  pdata->num_backlights, NULL, 0, NULL);
427  if (ret) {
428  dev_err(lm3533->dev, "failed to add backlight devices\n");
429  return ret;
430  }
431 
432  lm3533->have_backlights = 1;
433 
434  return 0;
435 }
436 
437 static int __devinit lm3533_device_led_init(struct lm3533 *lm3533)
438 {
439  struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
440  int i;
441  int ret;
442 
443  if (!pdata->leds || pdata->num_leds == 0)
444  return 0;
445 
446  if (pdata->num_leds > ARRAY_SIZE(lm3533_led_devs))
447  pdata->num_leds = ARRAY_SIZE(lm3533_led_devs);
448 
449  for (i = 0; i < pdata->num_leds; ++i) {
450  lm3533_led_devs[i].platform_data = &pdata->leds[i];
451  lm3533_led_devs[i].pdata_size = sizeof(pdata->leds[i]);
452  }
453 
454  ret = mfd_add_devices(lm3533->dev, 0, lm3533_led_devs,
455  pdata->num_leds, NULL, 0, NULL);
456  if (ret) {
457  dev_err(lm3533->dev, "failed to add LED devices\n");
458  return ret;
459  }
460 
461  lm3533->have_leds = 1;
462 
463  return 0;
464 }
465 
466 static int __devinit lm3533_device_setup(struct lm3533 *lm3533,
467  struct lm3533_platform_data *pdata)
468 {
469  int ret;
470 
471  ret = lm3533_set_boost_freq(lm3533, pdata->boost_freq);
472  if (ret)
473  return ret;
474 
475  ret = lm3533_set_boost_ovp(lm3533, pdata->boost_ovp);
476  if (ret)
477  return ret;
478 
479  return 0;
480 }
481 
482 static int __devinit lm3533_device_init(struct lm3533 *lm3533)
483 {
484  struct lm3533_platform_data *pdata = lm3533->dev->platform_data;
485  int ret;
486 
487  dev_dbg(lm3533->dev, "%s\n", __func__);
488 
489  if (!pdata) {
490  dev_err(lm3533->dev, "no platform data\n");
491  return -EINVAL;
492  }
493 
494  lm3533->gpio_hwen = pdata->gpio_hwen;
495 
496  dev_set_drvdata(lm3533->dev, lm3533);
497 
498  if (gpio_is_valid(lm3533->gpio_hwen)) {
500  "lm3533-hwen");
501  if (ret < 0) {
502  dev_err(lm3533->dev,
503  "failed to request HWEN GPIO %d\n",
504  lm3533->gpio_hwen);
505  return ret;
506  }
507  }
508 
509  lm3533_enable(lm3533);
510 
511  ret = lm3533_device_setup(lm3533, pdata);
512  if (ret)
513  goto err_disable;
514 
515  lm3533_device_als_init(lm3533);
516  lm3533_device_bl_init(lm3533);
517  lm3533_device_led_init(lm3533);
518 
519  ret = sysfs_create_group(&lm3533->dev->kobj, &lm3533_attribute_group);
520  if (ret < 0) {
521  dev_err(lm3533->dev, "failed to create sysfs attributes\n");
522  goto err_unregister;
523  }
524 
525  return 0;
526 
527 err_unregister:
528  mfd_remove_devices(lm3533->dev);
529 err_disable:
530  lm3533_disable(lm3533);
531  if (gpio_is_valid(lm3533->gpio_hwen))
532  gpio_free(lm3533->gpio_hwen);
533 
534  return ret;
535 }
536 
537 static void __devexit lm3533_device_exit(struct lm3533 *lm3533)
538 {
539  dev_dbg(lm3533->dev, "%s\n", __func__);
540 
541  sysfs_remove_group(&lm3533->dev->kobj, &lm3533_attribute_group);
542 
543  mfd_remove_devices(lm3533->dev);
544  lm3533_disable(lm3533);
545  if (gpio_is_valid(lm3533->gpio_hwen))
546  gpio_free(lm3533->gpio_hwen);
547 }
548 
549 static bool lm3533_readable_register(struct device *dev, unsigned int reg)
550 {
551  switch (reg) {
552  case 0x10 ... 0x2c:
553  case 0x30 ... 0x38:
554  case 0x40 ... 0x45:
555  case 0x50 ... 0x57:
556  case 0x60 ... 0x6e:
557  case 0x70 ... 0x75:
558  case 0x80 ... 0x85:
559  case 0x90 ... 0x95:
560  case 0xa0 ... 0xa5:
561  case 0xb0 ... 0xb2:
562  return true;
563  default:
564  return false;
565  }
566 }
567 
568 static bool lm3533_volatile_register(struct device *dev, unsigned int reg)
569 {
570  switch (reg) {
571  case 0x34 ... 0x36: /* zone */
572  case 0x37 ... 0x38: /* adc */
573  case 0xb0 ... 0xb1: /* fault */
574  return true;
575  default:
576  return false;
577  }
578 }
579 
580 static bool lm3533_precious_register(struct device *dev, unsigned int reg)
581 {
582  switch (reg) {
583  case 0x34: /* zone */
584  return true;
585  default:
586  return false;
587  }
588 }
589 
590 static struct regmap_config regmap_config = {
591  .reg_bits = 8,
592  .val_bits = 8,
593  .max_register = LM3533_REG_MAX,
594  .readable_reg = lm3533_readable_register,
595  .volatile_reg = lm3533_volatile_register,
596  .precious_reg = lm3533_precious_register,
597 };
598 
599 static int __devinit lm3533_i2c_probe(struct i2c_client *i2c,
600  const struct i2c_device_id *id)
601 {
602  struct lm3533 *lm3533;
603  int ret;
604 
605  dev_dbg(&i2c->dev, "%s\n", __func__);
606 
607  lm3533 = devm_kzalloc(&i2c->dev, sizeof(*lm3533), GFP_KERNEL);
608  if (!lm3533)
609  return -ENOMEM;
610 
611  i2c_set_clientdata(i2c, lm3533);
612 
613  lm3533->regmap = devm_regmap_init_i2c(i2c, &regmap_config);
614  if (IS_ERR(lm3533->regmap))
615  return PTR_ERR(lm3533->regmap);
616 
617  lm3533->dev = &i2c->dev;
618  lm3533->irq = i2c->irq;
619 
620  ret = lm3533_device_init(lm3533);
621  if (ret)
622  return ret;
623 
624  return 0;
625 }
626 
627 static int __devexit lm3533_i2c_remove(struct i2c_client *i2c)
628 {
629  struct lm3533 *lm3533 = i2c_get_clientdata(i2c);
630 
631  dev_dbg(&i2c->dev, "%s\n", __func__);
632 
633  lm3533_device_exit(lm3533);
634 
635  return 0;
636 }
637 
638 static const struct i2c_device_id lm3533_i2c_ids[] = {
639  { "lm3533", 0 },
640  { },
641 };
642 MODULE_DEVICE_TABLE(i2c, lm3533_i2c_ids);
643 
644 static struct i2c_driver lm3533_i2c_driver = {
645  .driver = {
646  .name = "lm3533",
647  .owner = THIS_MODULE,
648  },
649  .id_table = lm3533_i2c_ids,
650  .probe = lm3533_i2c_probe,
651  .remove = __devexit_p(lm3533_i2c_remove),
652 };
653 
654 static int __init lm3533_i2c_init(void)
655 {
656  return i2c_add_driver(&lm3533_i2c_driver);
657 }
658 subsys_initcall(lm3533_i2c_init);
659 
660 static void __exit lm3533_i2c_exit(void)
661 {
662  i2c_del_driver(&lm3533_i2c_driver);
663 }
664 module_exit(lm3533_i2c_exit);
665 
666 MODULE_AUTHOR("Johan Hovold <[email protected]>");
667 MODULE_DESCRIPTION("LM3533 Core");
668 MODULE_LICENSE("GPL");