UPSTREAM: arm64: dts: rockchip: add three new resets for rk3399 PCIe
[firefly-linux-kernel-4.4.55.git] / drivers / leds / leds-att1272.c
1 /*
2  * leds-att1272.c -  LED Driver
3  *
4  * Copyright (C) 2011 Rockchips
5  * deng dalong <ddl@rock-chips.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  *
11  * Datasheet: http://www.rohm.com/products/databook/driver/pdf/att1272gu-e.pdf
12  *
13  */
14
15 #include <linux/module.h>
16 #include <linux/i2c.h>
17 #include <linux/gpio.h>
18 #include <linux/delay.h>
19 #include <linux/leds.h>
20 #include <linux/leds-att1272.h>
21
22 static int debug;
23 module_param(debug, int, S_IRUGO|S_IWUSR);
24
25 #define dprintk(level, fmt, arg...) do {                        \
26         if (debug >= level)                                     \
27         printk(KERN_WARNING"leds-att1272: " fmt , ## arg); } while (0)
28
29 #define LEDS_ATT1272_TR(format, ...) printk(KERN_ERR format, ## __VA_ARGS__)
30 #define LEDS_ATT1272_DG(format, ...) dprintk(0, format, ## __VA_ARGS__)
31
32
33 struct att1272_led {
34         struct att1272_led_platform_data        *pdata;
35         struct i2c_client               *client;
36         struct rw_semaphore             rwsem;
37         struct work_struct              work;
38
39         /*
40          * Making led_classdev as array is not recommended, because array
41          * members prevent using 'container_of' macro. So repetitive works
42          * are needed.
43          */
44         struct led_classdev             cdev_led;
45
46         /* General attributes of LEDs */
47         int flash_safety_timeout;
48         int flash_safety_timeout_offset;
49         int movie_mode_current;
50         int movie_mode_current_offset;
51         int flash_to_movie_mode_ratio;
52         int flash_to_movie_mode_ratio_offset;
53         int flout_config;
54         int flout_config_offset;
55 };
56
57 static int att1272_write_byte(struct i2c_client *client, u8 reg, u8 val)
58 {
59     int err,cnt;
60         struct att1272_led *led = i2c_get_clientdata(client);
61     u8 buf[2];
62     struct i2c_msg msg[1];
63
64         gpio_set_value(led->pdata->en_gpio, 0);
65     buf[0] = reg & 0xFF;
66     buf[1] = val;
67
68     msg->addr = client->addr;
69     msg->flags = client->flags;
70     msg->buf = buf;
71     msg->len = sizeof(buf);
72     msg->scl_rate = 100000;         /* ddl@rock-chips.com : 100kHz */
73     msg->read_type = 0;               /* fpga i2c:0==I2C_NORMAL : direct use number not enum for don't want include spi_fpga.h */
74
75     cnt = 1;
76     err = -EAGAIN;
77         gpio_set_value(led->pdata->en_gpio, 1);
78     while ((cnt-- > 0) && (err < 0)) {                       /* ddl@rock-chips.com :  Transfer again if transent is failed   */
79         err = i2c_transfer(client->adapter, msg, 1);
80
81         if (err >= 0) {
82                         err = 0;
83             goto att1272_write_byte_end;
84         } else {
85                 LEDS_ATT1272_TR("\n write reg(0x%x, val:0x%x) failed, try to write again!\n",reg, val);
86                 udelay(10);
87         }
88     }
89
90 att1272_write_byte_end:
91         gpio_set_value(led->pdata->en_gpio, 0);
92         return err;
93 }
94
95 #define att1272_CONTROL_ATTR(attr_name, name_str,reg_addr, attr_together)                       \
96 static ssize_t att1272_show_##attr_name(struct device *dev,             \
97         struct device_attribute *attr, char *buf)                       \
98 {                                                                       \
99         struct att1272_led *led = i2c_get_clientdata(to_i2c_client(dev));\
100         ssize_t ret;                                                    \
101         LEDS_ATT1272_DG("%s enter\n",__FUNCTION__);    \
102         down_read(&led->rwsem);                                         \
103         ret = sprintf(buf, "0x%02x\n", led->attr_name);                 \
104         up_read(&led->rwsem);                                           \
105         return ret;                                                     \
106 }                                                                       \
107 static ssize_t att1272_store_##attr_name(struct device *dev,            \
108         struct device_attribute *attr, const char *buf, size_t count)   \
109 {                                                                       \
110         struct att1272_led *led = i2c_get_clientdata(to_i2c_client(dev));\
111         unsigned long val,val_w;                                                \
112         int ret;                                                        \
113         if (!count)                                                     \
114                 return -EINVAL;                                         \
115         ret = strict_strtoul(buf, 16, &val);                            \
116         if (ret)                                                        \
117                 return ret;                                             \
118         down_write(&led->rwsem);                                        \
119         val_w = (val<<led->attr_name##_offset);                 \
120         val_w |= (led->attr_together<<led->attr_together##_offset);\
121     LEDS_ATT1272_DG("%s enter, val:0x%x\n",__FUNCTION__,val_w);    \
122         if (att1272_write_byte(led->client, reg_addr, (u8) val) == 0) { \
123                 led->attr_name = val;                                           \
124         }                                                                                       \
125         up_write(&led->rwsem);                                          \
126         return count;                                                   \
127 }                                                                       \
128 static struct device_attribute att1272_##attr_name##_attr = {           \
129         .attr = {                                                       \
130                 .name = name_str,                                       \
131                 .mode = 0644,                                           \
132                 .owner = THIS_MODULE                                    \
133         },                                                              \
134         .show = att1272_show_##attr_name,                               \
135         .store = att1272_store_##attr_name,                             \
136 };
137
138 att1272_CONTROL_ATTR(flash_safety_timeout, "flash_safety_timeout",0x00,movie_mode_current);
139 att1272_CONTROL_ATTR(flash_to_movie_mode_ratio, "flash_to_movie_mode_ratio",0x01,flout_config);
140 att1272_CONTROL_ATTR(flout_config, "flout_config",0x01,flash_to_movie_mode_ratio);
141
142 static struct device_attribute *att1272_attributes[] = {
143         &att1272_flash_safety_timeout_attr,
144         &att1272_flash_to_movie_mode_ratio_attr,
145         &att1272_flout_config_attr,
146 };
147
148 static void att1272_led_work(struct work_struct *work)
149 {
150         struct att1272_led *led = container_of(work, struct att1272_led, work);
151
152         att1272_write_byte(led->client, 0x00, (u8)(led->movie_mode_current<<led->movie_mode_current_offset));
153         LEDS_ATT1272_DG();
154 }
155
156 static void att1272_set_led_brightness(struct led_classdev *led_cdev,
157                                         enum led_brightness value)
158 {
159         struct att1272_led *led =
160                 container_of(led_cdev, struct att1272_led, cdev_led);
161
162         led->movie_mode_current = led->cdev_led.max_brightness - (value>led->cdev_led.max_brightness)?led->cdev_led.max_brightness:value;
163         schedule_work(&led->work);
164 }
165 static int att1272_set_led_blink(struct led_classdev *led_cdev,
166                 unsigned long *delay_on, unsigned long *delay_off)
167 {
168         struct att1272_led *led =
169                 container_of(led_cdev, struct att1272_led, cdev_led);
170         if (*delay_on == 0 || *delay_off == 0)
171                 return -EINVAL;
172
173         schedule_work(&led->work);
174         return 0;
175 }
176
177 static int att1272_register_led_classdev(struct att1272_led *led)
178 {
179         int ret;
180         struct att1272_led_platform_data *pdata = led->client->dev.platform_data;
181
182         INIT_WORK(&led->work, att1272_led_work);
183
184         led->cdev_led.name = pdata->name;
185         led->cdev_led.brightness = LED_OFF;
186         led->cdev_led.max_brightness = 15;
187         led->cdev_led.brightness_set = att1272_set_led_brightness;
188         led->cdev_led.blink_set = att1272_set_led_blink;
189
190         ret = led_classdev_register(&led->client->dev, &led->cdev_led);
191         if (ret < 0) {
192                 LEDS_ATT1272_TR("couldn't register LED %s\n",
193                                                         led->cdev_led.name);
194                 goto failed_unregister_led;
195         }
196
197
198         return 0;
199
200 failed_unregister_led:
201
202         return ret;
203 }
204
205 static void att1272_unregister_led_classdev(struct att1272_led *led)
206 {
207         cancel_work_sync(&led->work);
208         led_classdev_unregister(&led->cdev_led);
209 }
210
211 static int __devinit att1272_probe(struct i2c_client *client,
212                         const struct i2c_device_id *id)
213 {
214         struct att1272_led *led;
215         struct att1272_led_platform_data *pdata;
216         int ret, i;
217
218         LEDS_ATT1272_DG("%s enter: client->addr:0x%x\n",__FUNCTION__,client->addr);
219
220         led = kzalloc(sizeof(struct att1272_led), GFP_KERNEL);
221         if (!led) {
222                 LEDS_ATT1272_TR("failed to allocate driver data\n");
223                 return -ENOMEM;
224         }
225
226         led->client = client;
227         pdata = led->pdata = client->dev.platform_data;
228         i2c_set_clientdata(client, led);
229
230         /* Configure EN GPIO  */
231         if (gpio_request(pdata->en_gpio, "ATT1272_EN") < 0) {
232                 LEDS_ATT1272_TR("request en_gpio(%d) is failed!\n",pdata->en_gpio);
233                 goto failed_free;
234         }
235         gpio_direction_output(pdata->en_gpio, 0);
236
237         /* Detect att1272 */
238         printk("att1272 i2c write.....\n");
239         ret = att1272_write_byte(client, 0x01, 0x30);
240         ret |= att1272_write_byte(client, 0x00, 0x00);
241         if (ret < 0) {
242                 LEDS_ATT1272_TR("failed to detect device\n");
243                 goto failed_free;
244         }
245
246         /* Default attributes */
247         led->flash_safety_timeout = 0x00;
248         led->flash_safety_timeout_offset = 0x00;
249         led->movie_mode_current = 0x00;
250         led->movie_mode_current_offset = 0x04;
251         led->flash_to_movie_mode_ratio = 0x03;
252         led->flash_to_movie_mode_ratio_offset = 0x03;
253         led->flout_config = 0x00;
254         led->flout_config_offset = 0x04;
255
256         init_rwsem(&led->rwsem);
257
258         for (i = 0; i < ARRAY_SIZE(att1272_attributes); i++) {
259                 ret = device_create_file(&led->client->dev,
260                                                 att1272_attributes[i]);
261                 if (ret) {
262                         LEDS_ATT1272_TR("failed: sysfs file %s\n",
263                                         att1272_attributes[i]->attr.name);
264                         goto failed_unregister_dev_file;
265                 }
266         }
267
268         ret = att1272_register_led_classdev(led);
269         if (ret < 0)
270                 goto failed_unregister_dev_file;
271
272         return 0;
273
274 failed_unregister_dev_file:
275         for (i--; i >= 0; i--)
276                 device_remove_file(&led->client->dev, att1272_attributes[i]);
277 failed_free:
278         i2c_set_clientdata(client, NULL);
279         kfree(led);
280
281         return ret;
282 }
283
284 static int __exit att1272_remove(struct i2c_client *client)
285 {
286         struct att1272_led *led = i2c_get_clientdata(client);
287         int i;
288
289         gpio_set_value(led->pdata->en_gpio, 0);
290         att1272_unregister_led_classdev(led);
291
292         for (i = 0; i < ARRAY_SIZE(att1272_attributes); i++)
293                 device_remove_file(&led->client->dev, att1272_attributes[i]);
294         i2c_set_clientdata(client, NULL);
295         kfree(led);
296
297         return 0;
298 }
299
300 static int att1272_suspend(struct i2c_client *client, pm_message_t mesg)
301 {
302         struct att1272_led *led = i2c_get_clientdata(client);
303
304         return 0;
305 }
306
307 static int att1272_resume(struct i2c_client *client)
308 {
309         struct att1272_led *led = i2c_get_clientdata(client);
310
311         return 0;
312 }
313
314 static const struct i2c_device_id att1272_id[] = {
315         { "att1272", 0 },
316         { }
317 };
318 MODULE_DEVICE_TABLE(i2c, att1272_id);
319
320 static struct i2c_driver att1272_i2c_driver = {
321         .driver = {
322                 .name   = "att1272",
323         },
324         .probe          = att1272_probe,
325         .remove         = __exit_p(att1272_remove),
326         .suspend        = att1272_suspend,
327         .resume         = att1272_resume,
328         .id_table       = att1272_id,
329 };
330
331 static int __init att1272_init(void)
332 {
333         return i2c_add_driver(&att1272_i2c_driver);
334 }
335 module_init(att1272_init);
336
337 static void __exit att1272_exit(void)
338 {
339         i2c_del_driver(&att1272_i2c_driver);
340 }
341 module_exit(att1272_exit);
342
343 MODULE_AUTHOR("deng dalong <ddl@rock-chips.com>");
344 MODULE_DESCRIPTION("att1272 LED driver");
345 MODULE_LICENSE("GPL v2");
346