Commit 87aae1ea82f93f0f00cb955044ea1db3501cf233

Authored by Jingoo Han
Committed by Bryan Wu
1 parent 8465b01827

leds: use dev_get_platdata()

Use the wrapper function for retrieving the platform data instead of
accessing dev->platform_data directly.

Signed-off-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Bryan Wu <cooloney@gmail.com>

Showing 30 changed files with 52 additions and 49 deletions Inline Diff

drivers/leds/leds-88pm860x.c
1 /* 1 /*
2 * LED driver for Marvell 88PM860x 2 * LED driver for Marvell 88PM860x
3 * 3 *
4 * Copyright (C) 2009 Marvell International Ltd. 4 * Copyright (C) 2009 Marvell International Ltd.
5 * Haojian Zhuang <haojian.zhuang@marvell.com> 5 * Haojian Zhuang <haojian.zhuang@marvell.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 * 10 *
11 */ 11 */
12 12
13 #include <linux/kernel.h> 13 #include <linux/kernel.h>
14 #include <linux/init.h> 14 #include <linux/init.h>
15 #include <linux/of.h> 15 #include <linux/of.h>
16 #include <linux/platform_device.h> 16 #include <linux/platform_device.h>
17 #include <linux/i2c.h> 17 #include <linux/i2c.h>
18 #include <linux/leds.h> 18 #include <linux/leds.h>
19 #include <linux/slab.h> 19 #include <linux/slab.h>
20 #include <linux/workqueue.h> 20 #include <linux/workqueue.h>
21 #include <linux/mfd/88pm860x.h> 21 #include <linux/mfd/88pm860x.h>
22 #include <linux/module.h> 22 #include <linux/module.h>
23 23
24 #define LED_PWM_MASK (0x1F) 24 #define LED_PWM_MASK (0x1F)
25 #define LED_CURRENT_MASK (0x07 << 5) 25 #define LED_CURRENT_MASK (0x07 << 5)
26 26
27 #define LED_BLINK_MASK (0x7F) 27 #define LED_BLINK_MASK (0x7F)
28 28
29 #define LED_ON_CONTINUOUS (0x0F << 3) 29 #define LED_ON_CONTINUOUS (0x0F << 3)
30 30
31 #define LED1_BLINK_EN (1 << 1) 31 #define LED1_BLINK_EN (1 << 1)
32 #define LED2_BLINK_EN (1 << 2) 32 #define LED2_BLINK_EN (1 << 2)
33 33
34 struct pm860x_led { 34 struct pm860x_led {
35 struct led_classdev cdev; 35 struct led_classdev cdev;
36 struct i2c_client *i2c; 36 struct i2c_client *i2c;
37 struct work_struct work; 37 struct work_struct work;
38 struct pm860x_chip *chip; 38 struct pm860x_chip *chip;
39 struct mutex lock; 39 struct mutex lock;
40 char name[MFD_NAME_SIZE]; 40 char name[MFD_NAME_SIZE];
41 41
42 int port; 42 int port;
43 int iset; 43 int iset;
44 unsigned char brightness; 44 unsigned char brightness;
45 unsigned char current_brightness; 45 unsigned char current_brightness;
46 46
47 int reg_control; 47 int reg_control;
48 int reg_blink; 48 int reg_blink;
49 int blink_mask; 49 int blink_mask;
50 }; 50 };
51 51
52 static int led_power_set(struct pm860x_chip *chip, int port, int on) 52 static int led_power_set(struct pm860x_chip *chip, int port, int on)
53 { 53 {
54 int ret = -EINVAL; 54 int ret = -EINVAL;
55 55
56 switch (port) { 56 switch (port) {
57 case 0: 57 case 0:
58 case 1: 58 case 1:
59 case 2: 59 case 2:
60 ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) : 60 ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) :
61 pm8606_osc_disable(chip, RGB1_ENABLE); 61 pm8606_osc_disable(chip, RGB1_ENABLE);
62 break; 62 break;
63 case 3: 63 case 3:
64 case 4: 64 case 4:
65 case 5: 65 case 5:
66 ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) : 66 ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) :
67 pm8606_osc_disable(chip, RGB2_ENABLE); 67 pm8606_osc_disable(chip, RGB2_ENABLE);
68 break; 68 break;
69 } 69 }
70 return ret; 70 return ret;
71 } 71 }
72 72
73 static void pm860x_led_work(struct work_struct *work) 73 static void pm860x_led_work(struct work_struct *work)
74 { 74 {
75 75
76 struct pm860x_led *led; 76 struct pm860x_led *led;
77 struct pm860x_chip *chip; 77 struct pm860x_chip *chip;
78 unsigned char buf[3]; 78 unsigned char buf[3];
79 int ret; 79 int ret;
80 80
81 led = container_of(work, struct pm860x_led, work); 81 led = container_of(work, struct pm860x_led, work);
82 chip = led->chip; 82 chip = led->chip;
83 mutex_lock(&led->lock); 83 mutex_lock(&led->lock);
84 if ((led->current_brightness == 0) && led->brightness) { 84 if ((led->current_brightness == 0) && led->brightness) {
85 led_power_set(chip, led->port, 1); 85 led_power_set(chip, led->port, 1);
86 if (led->iset) { 86 if (led->iset) {
87 pm860x_set_bits(led->i2c, led->reg_control, 87 pm860x_set_bits(led->i2c, led->reg_control,
88 LED_CURRENT_MASK, led->iset); 88 LED_CURRENT_MASK, led->iset);
89 } 89 }
90 pm860x_set_bits(led->i2c, led->reg_blink, 90 pm860x_set_bits(led->i2c, led->reg_blink,
91 LED_BLINK_MASK, LED_ON_CONTINUOUS); 91 LED_BLINK_MASK, LED_ON_CONTINUOUS);
92 pm860x_set_bits(led->i2c, PM8606_WLED3B, led->blink_mask, 92 pm860x_set_bits(led->i2c, PM8606_WLED3B, led->blink_mask,
93 led->blink_mask); 93 led->blink_mask);
94 } 94 }
95 pm860x_set_bits(led->i2c, led->reg_control, LED_PWM_MASK, 95 pm860x_set_bits(led->i2c, led->reg_control, LED_PWM_MASK,
96 led->brightness); 96 led->brightness);
97 97
98 if (led->brightness == 0) { 98 if (led->brightness == 0) {
99 pm860x_bulk_read(led->i2c, led->reg_control, 3, buf); 99 pm860x_bulk_read(led->i2c, led->reg_control, 3, buf);
100 ret = buf[0] & LED_PWM_MASK; 100 ret = buf[0] & LED_PWM_MASK;
101 ret |= buf[1] & LED_PWM_MASK; 101 ret |= buf[1] & LED_PWM_MASK;
102 ret |= buf[2] & LED_PWM_MASK; 102 ret |= buf[2] & LED_PWM_MASK;
103 if (ret == 0) { 103 if (ret == 0) {
104 /* unset current since no led is lighting */ 104 /* unset current since no led is lighting */
105 pm860x_set_bits(led->i2c, led->reg_control, 105 pm860x_set_bits(led->i2c, led->reg_control,
106 LED_CURRENT_MASK, 0); 106 LED_CURRENT_MASK, 0);
107 pm860x_set_bits(led->i2c, PM8606_WLED3B, 107 pm860x_set_bits(led->i2c, PM8606_WLED3B,
108 led->blink_mask, 0); 108 led->blink_mask, 0);
109 led_power_set(chip, led->port, 0); 109 led_power_set(chip, led->port, 0);
110 } 110 }
111 } 111 }
112 led->current_brightness = led->brightness; 112 led->current_brightness = led->brightness;
113 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n", 113 dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
114 led->reg_control, led->brightness); 114 led->reg_control, led->brightness);
115 mutex_unlock(&led->lock); 115 mutex_unlock(&led->lock);
116 } 116 }
117 117
118 static void pm860x_led_set(struct led_classdev *cdev, 118 static void pm860x_led_set(struct led_classdev *cdev,
119 enum led_brightness value) 119 enum led_brightness value)
120 { 120 {
121 struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev); 121 struct pm860x_led *data = container_of(cdev, struct pm860x_led, cdev);
122 122
123 data->brightness = value >> 3; 123 data->brightness = value >> 3;
124 schedule_work(&data->work); 124 schedule_work(&data->work);
125 } 125 }
126 126
127 #ifdef CONFIG_OF 127 #ifdef CONFIG_OF
128 static int pm860x_led_dt_init(struct platform_device *pdev, 128 static int pm860x_led_dt_init(struct platform_device *pdev,
129 struct pm860x_led *data) 129 struct pm860x_led *data)
130 { 130 {
131 struct device_node *nproot, *np; 131 struct device_node *nproot, *np;
132 int iset = 0; 132 int iset = 0;
133 133
134 nproot = of_node_get(pdev->dev.parent->of_node); 134 nproot = of_node_get(pdev->dev.parent->of_node);
135 if (!nproot) 135 if (!nproot)
136 return -ENODEV; 136 return -ENODEV;
137 nproot = of_find_node_by_name(nproot, "leds"); 137 nproot = of_find_node_by_name(nproot, "leds");
138 if (!nproot) { 138 if (!nproot) {
139 dev_err(&pdev->dev, "failed to find leds node\n"); 139 dev_err(&pdev->dev, "failed to find leds node\n");
140 return -ENODEV; 140 return -ENODEV;
141 } 141 }
142 for_each_child_of_node(nproot, np) { 142 for_each_child_of_node(nproot, np) {
143 if (!of_node_cmp(np->name, data->name)) { 143 if (!of_node_cmp(np->name, data->name)) {
144 of_property_read_u32(np, "marvell,88pm860x-iset", 144 of_property_read_u32(np, "marvell,88pm860x-iset",
145 &iset); 145 &iset);
146 data->iset = PM8606_LED_CURRENT(iset); 146 data->iset = PM8606_LED_CURRENT(iset);
147 break; 147 break;
148 } 148 }
149 } 149 }
150 of_node_put(nproot); 150 of_node_put(nproot);
151 return 0; 151 return 0;
152 } 152 }
153 #else 153 #else
154 #define pm860x_led_dt_init(x, y) (-1) 154 #define pm860x_led_dt_init(x, y) (-1)
155 #endif 155 #endif
156 156
157 static int pm860x_led_probe(struct platform_device *pdev) 157 static int pm860x_led_probe(struct platform_device *pdev)
158 { 158 {
159 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent); 159 struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
160 struct pm860x_led_pdata *pdata = pdev->dev.platform_data; 160 struct pm860x_led_pdata *pdata = dev_get_platdata(&pdev->dev);
161 struct pm860x_led *data; 161 struct pm860x_led *data;
162 struct resource *res; 162 struct resource *res;
163 int ret = 0; 163 int ret = 0;
164 164
165 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL); 165 data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL);
166 if (data == NULL) 166 if (data == NULL)
167 return -ENOMEM; 167 return -ENOMEM;
168 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "control"); 168 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "control");
169 if (!res) { 169 if (!res) {
170 dev_err(&pdev->dev, "No REG resource for control\n"); 170 dev_err(&pdev->dev, "No REG resource for control\n");
171 return -ENXIO; 171 return -ENXIO;
172 } 172 }
173 data->reg_control = res->start; 173 data->reg_control = res->start;
174 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "blink"); 174 res = platform_get_resource_byname(pdev, IORESOURCE_REG, "blink");
175 if (!res) { 175 if (!res) {
176 dev_err(&pdev->dev, "No REG resource for blink\n"); 176 dev_err(&pdev->dev, "No REG resource for blink\n");
177 return -ENXIO; 177 return -ENXIO;
178 } 178 }
179 data->reg_blink = res->start; 179 data->reg_blink = res->start;
180 memset(data->name, 0, MFD_NAME_SIZE); 180 memset(data->name, 0, MFD_NAME_SIZE);
181 switch (pdev->id) { 181 switch (pdev->id) {
182 case 0: 182 case 0:
183 data->blink_mask = LED1_BLINK_EN; 183 data->blink_mask = LED1_BLINK_EN;
184 sprintf(data->name, "led0-red"); 184 sprintf(data->name, "led0-red");
185 break; 185 break;
186 case 1: 186 case 1:
187 data->blink_mask = LED1_BLINK_EN; 187 data->blink_mask = LED1_BLINK_EN;
188 sprintf(data->name, "led0-green"); 188 sprintf(data->name, "led0-green");
189 break; 189 break;
190 case 2: 190 case 2:
191 data->blink_mask = LED1_BLINK_EN; 191 data->blink_mask = LED1_BLINK_EN;
192 sprintf(data->name, "led0-blue"); 192 sprintf(data->name, "led0-blue");
193 break; 193 break;
194 case 3: 194 case 3:
195 data->blink_mask = LED2_BLINK_EN; 195 data->blink_mask = LED2_BLINK_EN;
196 sprintf(data->name, "led1-red"); 196 sprintf(data->name, "led1-red");
197 break; 197 break;
198 case 4: 198 case 4:
199 data->blink_mask = LED2_BLINK_EN; 199 data->blink_mask = LED2_BLINK_EN;
200 sprintf(data->name, "led1-green"); 200 sprintf(data->name, "led1-green");
201 break; 201 break;
202 case 5: 202 case 5:
203 data->blink_mask = LED2_BLINK_EN; 203 data->blink_mask = LED2_BLINK_EN;
204 sprintf(data->name, "led1-blue"); 204 sprintf(data->name, "led1-blue");
205 break; 205 break;
206 } 206 }
207 platform_set_drvdata(pdev, data); 207 platform_set_drvdata(pdev, data);
208 data->chip = chip; 208 data->chip = chip;
209 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion; 209 data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
210 data->port = pdev->id; 210 data->port = pdev->id;
211 if (pm860x_led_dt_init(pdev, data)) 211 if (pm860x_led_dt_init(pdev, data))
212 if (pdata) 212 if (pdata)
213 data->iset = pdata->iset; 213 data->iset = pdata->iset;
214 214
215 data->current_brightness = 0; 215 data->current_brightness = 0;
216 data->cdev.name = data->name; 216 data->cdev.name = data->name;
217 data->cdev.brightness_set = pm860x_led_set; 217 data->cdev.brightness_set = pm860x_led_set;
218 mutex_init(&data->lock); 218 mutex_init(&data->lock);
219 INIT_WORK(&data->work, pm860x_led_work); 219 INIT_WORK(&data->work, pm860x_led_work);
220 220
221 ret = led_classdev_register(chip->dev, &data->cdev); 221 ret = led_classdev_register(chip->dev, &data->cdev);
222 if (ret < 0) { 222 if (ret < 0) {
223 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 223 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
224 return ret; 224 return ret;
225 } 225 }
226 pm860x_led_set(&data->cdev, 0); 226 pm860x_led_set(&data->cdev, 0);
227 return 0; 227 return 0;
228 } 228 }
229 229
230 static int pm860x_led_remove(struct platform_device *pdev) 230 static int pm860x_led_remove(struct platform_device *pdev)
231 { 231 {
232 struct pm860x_led *data = platform_get_drvdata(pdev); 232 struct pm860x_led *data = platform_get_drvdata(pdev);
233 233
234 led_classdev_unregister(&data->cdev); 234 led_classdev_unregister(&data->cdev);
235 235
236 return 0; 236 return 0;
237 } 237 }
238 238
239 static struct platform_driver pm860x_led_driver = { 239 static struct platform_driver pm860x_led_driver = {
240 .driver = { 240 .driver = {
241 .name = "88pm860x-led", 241 .name = "88pm860x-led",
242 .owner = THIS_MODULE, 242 .owner = THIS_MODULE,
243 }, 243 },
244 .probe = pm860x_led_probe, 244 .probe = pm860x_led_probe,
245 .remove = pm860x_led_remove, 245 .remove = pm860x_led_remove,
246 }; 246 };
247 247
248 module_platform_driver(pm860x_led_driver); 248 module_platform_driver(pm860x_led_driver);
249 249
250 MODULE_DESCRIPTION("LED driver for Marvell PM860x"); 250 MODULE_DESCRIPTION("LED driver for Marvell PM860x");
251 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 251 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
252 MODULE_LICENSE("GPL"); 252 MODULE_LICENSE("GPL");
253 MODULE_ALIAS("platform:88pm860x-led"); 253 MODULE_ALIAS("platform:88pm860x-led");
254 254
drivers/leds/leds-adp5520.c
1 /* 1 /*
2 * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs 2 * LEDs driver for Analog Devices ADP5520/ADP5501 MFD PMICs
3 * 3 *
4 * Copyright 2009 Analog Devices Inc. 4 * Copyright 2009 Analog Devices Inc.
5 * 5 *
6 * Loosely derived from leds-da903x: 6 * Loosely derived from leds-da903x:
7 * Copyright (C) 2008 Compulab, Ltd. 7 * Copyright (C) 2008 Compulab, Ltd.
8 * Mike Rapoport <mike@compulab.co.il> 8 * Mike Rapoport <mike@compulab.co.il>
9 * 9 *
10 * Copyright (C) 2006-2008 Marvell International Ltd. 10 * Copyright (C) 2006-2008 Marvell International Ltd.
11 * Eric Miao <eric.miao@marvell.com> 11 * Eric Miao <eric.miao@marvell.com>
12 * 12 *
13 * Licensed under the GPL-2 or later. 13 * Licensed under the GPL-2 or later.
14 */ 14 */
15 15
16 #include <linux/module.h> 16 #include <linux/module.h>
17 #include <linux/kernel.h> 17 #include <linux/kernel.h>
18 #include <linux/init.h> 18 #include <linux/init.h>
19 #include <linux/platform_device.h> 19 #include <linux/platform_device.h>
20 #include <linux/leds.h> 20 #include <linux/leds.h>
21 #include <linux/workqueue.h> 21 #include <linux/workqueue.h>
22 #include <linux/mfd/adp5520.h> 22 #include <linux/mfd/adp5520.h>
23 #include <linux/slab.h> 23 #include <linux/slab.h>
24 24
25 struct adp5520_led { 25 struct adp5520_led {
26 struct led_classdev cdev; 26 struct led_classdev cdev;
27 struct work_struct work; 27 struct work_struct work;
28 struct device *master; 28 struct device *master;
29 enum led_brightness new_brightness; 29 enum led_brightness new_brightness;
30 int id; 30 int id;
31 int flags; 31 int flags;
32 }; 32 };
33 33
34 static void adp5520_led_work(struct work_struct *work) 34 static void adp5520_led_work(struct work_struct *work)
35 { 35 {
36 struct adp5520_led *led = container_of(work, struct adp5520_led, work); 36 struct adp5520_led *led = container_of(work, struct adp5520_led, work);
37 adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1, 37 adp5520_write(led->master, ADP5520_LED1_CURRENT + led->id - 1,
38 led->new_brightness >> 2); 38 led->new_brightness >> 2);
39 } 39 }
40 40
41 static void adp5520_led_set(struct led_classdev *led_cdev, 41 static void adp5520_led_set(struct led_classdev *led_cdev,
42 enum led_brightness value) 42 enum led_brightness value)
43 { 43 {
44 struct adp5520_led *led; 44 struct adp5520_led *led;
45 45
46 led = container_of(led_cdev, struct adp5520_led, cdev); 46 led = container_of(led_cdev, struct adp5520_led, cdev);
47 led->new_brightness = value; 47 led->new_brightness = value;
48 schedule_work(&led->work); 48 schedule_work(&led->work);
49 } 49 }
50 50
51 static int adp5520_led_setup(struct adp5520_led *led) 51 static int adp5520_led_setup(struct adp5520_led *led)
52 { 52 {
53 struct device *dev = led->master; 53 struct device *dev = led->master;
54 int flags = led->flags; 54 int flags = led->flags;
55 int ret = 0; 55 int ret = 0;
56 56
57 switch (led->id) { 57 switch (led->id) {
58 case FLAG_ID_ADP5520_LED1_ADP5501_LED0: 58 case FLAG_ID_ADP5520_LED1_ADP5501_LED0:
59 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, 59 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
60 (flags >> ADP5520_FLAG_OFFT_SHIFT) & 60 (flags >> ADP5520_FLAG_OFFT_SHIFT) &
61 ADP5520_FLAG_OFFT_MASK); 61 ADP5520_FLAG_OFFT_MASK);
62 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, 62 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
63 ADP5520_LED1_EN); 63 ADP5520_LED1_EN);
64 break; 64 break;
65 case FLAG_ID_ADP5520_LED2_ADP5501_LED1: 65 case FLAG_ID_ADP5520_LED2_ADP5501_LED1:
66 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, 66 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
67 ((flags >> ADP5520_FLAG_OFFT_SHIFT) & 67 ((flags >> ADP5520_FLAG_OFFT_SHIFT) &
68 ADP5520_FLAG_OFFT_MASK) << 2); 68 ADP5520_FLAG_OFFT_MASK) << 2);
69 ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL, 69 ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
70 ADP5520_R3_MODE); 70 ADP5520_R3_MODE);
71 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, 71 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
72 ADP5520_LED2_EN); 72 ADP5520_LED2_EN);
73 break; 73 break;
74 case FLAG_ID_ADP5520_LED3_ADP5501_LED2: 74 case FLAG_ID_ADP5520_LED3_ADP5501_LED2:
75 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME, 75 ret |= adp5520_set_bits(dev, ADP5520_LED_TIME,
76 ((flags >> ADP5520_FLAG_OFFT_SHIFT) & 76 ((flags >> ADP5520_FLAG_OFFT_SHIFT) &
77 ADP5520_FLAG_OFFT_MASK) << 4); 77 ADP5520_FLAG_OFFT_MASK) << 4);
78 ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL, 78 ret |= adp5520_clr_bits(dev, ADP5520_LED_CONTROL,
79 ADP5520_C3_MODE); 79 ADP5520_C3_MODE);
80 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL, 80 ret |= adp5520_set_bits(dev, ADP5520_LED_CONTROL,
81 ADP5520_LED3_EN); 81 ADP5520_LED3_EN);
82 break; 82 break;
83 } 83 }
84 84
85 return ret; 85 return ret;
86 } 86 }
87 87
88 static int adp5520_led_prepare(struct platform_device *pdev) 88 static int adp5520_led_prepare(struct platform_device *pdev)
89 { 89 {
90 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; 90 struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
91 struct device *dev = pdev->dev.parent; 91 struct device *dev = pdev->dev.parent;
92 int ret = 0; 92 int ret = 0;
93 93
94 ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0); 94 ret |= adp5520_write(dev, ADP5520_LED1_CURRENT, 0);
95 ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0); 95 ret |= adp5520_write(dev, ADP5520_LED2_CURRENT, 0);
96 ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0); 96 ret |= adp5520_write(dev, ADP5520_LED3_CURRENT, 0);
97 ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6); 97 ret |= adp5520_write(dev, ADP5520_LED_TIME, pdata->led_on_time << 6);
98 ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in, 98 ret |= adp5520_write(dev, ADP5520_LED_FADE, FADE_VAL(pdata->fade_in,
99 pdata->fade_out)); 99 pdata->fade_out));
100 100
101 return ret; 101 return ret;
102 } 102 }
103 103
104 static int adp5520_led_probe(struct platform_device *pdev) 104 static int adp5520_led_probe(struct platform_device *pdev)
105 { 105 {
106 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; 106 struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
107 struct adp5520_led *led, *led_dat; 107 struct adp5520_led *led, *led_dat;
108 struct led_info *cur_led; 108 struct led_info *cur_led;
109 int ret, i; 109 int ret, i;
110 110
111 if (pdata == NULL) { 111 if (pdata == NULL) {
112 dev_err(&pdev->dev, "missing platform data\n"); 112 dev_err(&pdev->dev, "missing platform data\n");
113 return -ENODEV; 113 return -ENODEV;
114 } 114 }
115 115
116 if (pdata->num_leds > ADP5520_01_MAXLEDS) { 116 if (pdata->num_leds > ADP5520_01_MAXLEDS) {
117 dev_err(&pdev->dev, "can't handle more than %d LEDS\n", 117 dev_err(&pdev->dev, "can't handle more than %d LEDS\n",
118 ADP5520_01_MAXLEDS); 118 ADP5520_01_MAXLEDS);
119 return -EFAULT; 119 return -EFAULT;
120 } 120 }
121 121
122 led = devm_kzalloc(&pdev->dev, sizeof(*led) * pdata->num_leds, 122 led = devm_kzalloc(&pdev->dev, sizeof(*led) * pdata->num_leds,
123 GFP_KERNEL); 123 GFP_KERNEL);
124 if (led == NULL) { 124 if (led == NULL) {
125 dev_err(&pdev->dev, "failed to alloc memory\n"); 125 dev_err(&pdev->dev, "failed to alloc memory\n");
126 return -ENOMEM; 126 return -ENOMEM;
127 } 127 }
128 128
129 ret = adp5520_led_prepare(pdev); 129 ret = adp5520_led_prepare(pdev);
130 130
131 if (ret) { 131 if (ret) {
132 dev_err(&pdev->dev, "failed to write\n"); 132 dev_err(&pdev->dev, "failed to write\n");
133 return ret; 133 return ret;
134 } 134 }
135 135
136 for (i = 0; i < pdata->num_leds; ++i) { 136 for (i = 0; i < pdata->num_leds; ++i) {
137 cur_led = &pdata->leds[i]; 137 cur_led = &pdata->leds[i];
138 led_dat = &led[i]; 138 led_dat = &led[i];
139 139
140 led_dat->cdev.name = cur_led->name; 140 led_dat->cdev.name = cur_led->name;
141 led_dat->cdev.default_trigger = cur_led->default_trigger; 141 led_dat->cdev.default_trigger = cur_led->default_trigger;
142 led_dat->cdev.brightness_set = adp5520_led_set; 142 led_dat->cdev.brightness_set = adp5520_led_set;
143 led_dat->cdev.brightness = LED_OFF; 143 led_dat->cdev.brightness = LED_OFF;
144 144
145 if (cur_led->flags & ADP5520_FLAG_LED_MASK) 145 if (cur_led->flags & ADP5520_FLAG_LED_MASK)
146 led_dat->flags = cur_led->flags; 146 led_dat->flags = cur_led->flags;
147 else 147 else
148 led_dat->flags = i + 1; 148 led_dat->flags = i + 1;
149 149
150 led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK; 150 led_dat->id = led_dat->flags & ADP5520_FLAG_LED_MASK;
151 151
152 led_dat->master = pdev->dev.parent; 152 led_dat->master = pdev->dev.parent;
153 led_dat->new_brightness = LED_OFF; 153 led_dat->new_brightness = LED_OFF;
154 154
155 INIT_WORK(&led_dat->work, adp5520_led_work); 155 INIT_WORK(&led_dat->work, adp5520_led_work);
156 156
157 ret = led_classdev_register(led_dat->master, &led_dat->cdev); 157 ret = led_classdev_register(led_dat->master, &led_dat->cdev);
158 if (ret) { 158 if (ret) {
159 dev_err(&pdev->dev, "failed to register LED %d\n", 159 dev_err(&pdev->dev, "failed to register LED %d\n",
160 led_dat->id); 160 led_dat->id);
161 goto err; 161 goto err;
162 } 162 }
163 163
164 ret = adp5520_led_setup(led_dat); 164 ret = adp5520_led_setup(led_dat);
165 if (ret) { 165 if (ret) {
166 dev_err(&pdev->dev, "failed to write\n"); 166 dev_err(&pdev->dev, "failed to write\n");
167 i++; 167 i++;
168 goto err; 168 goto err;
169 } 169 }
170 } 170 }
171 171
172 platform_set_drvdata(pdev, led); 172 platform_set_drvdata(pdev, led);
173 return 0; 173 return 0;
174 174
175 err: 175 err:
176 if (i > 0) { 176 if (i > 0) {
177 for (i = i - 1; i >= 0; i--) { 177 for (i = i - 1; i >= 0; i--) {
178 led_classdev_unregister(&led[i].cdev); 178 led_classdev_unregister(&led[i].cdev);
179 cancel_work_sync(&led[i].work); 179 cancel_work_sync(&led[i].work);
180 } 180 }
181 } 181 }
182 182
183 return ret; 183 return ret;
184 } 184 }
185 185
186 static int adp5520_led_remove(struct platform_device *pdev) 186 static int adp5520_led_remove(struct platform_device *pdev)
187 { 187 {
188 struct adp5520_leds_platform_data *pdata = pdev->dev.platform_data; 188 struct adp5520_leds_platform_data *pdata = dev_get_platdata(&pdev->dev);
189 struct adp5520_led *led; 189 struct adp5520_led *led;
190 int i; 190 int i;
191 191
192 led = platform_get_drvdata(pdev); 192 led = platform_get_drvdata(pdev);
193 193
194 adp5520_clr_bits(led->master, ADP5520_LED_CONTROL, 194 adp5520_clr_bits(led->master, ADP5520_LED_CONTROL,
195 ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN); 195 ADP5520_LED1_EN | ADP5520_LED2_EN | ADP5520_LED3_EN);
196 196
197 for (i = 0; i < pdata->num_leds; i++) { 197 for (i = 0; i < pdata->num_leds; i++) {
198 led_classdev_unregister(&led[i].cdev); 198 led_classdev_unregister(&led[i].cdev);
199 cancel_work_sync(&led[i].work); 199 cancel_work_sync(&led[i].work);
200 } 200 }
201 201
202 return 0; 202 return 0;
203 } 203 }
204 204
205 static struct platform_driver adp5520_led_driver = { 205 static struct platform_driver adp5520_led_driver = {
206 .driver = { 206 .driver = {
207 .name = "adp5520-led", 207 .name = "adp5520-led",
208 .owner = THIS_MODULE, 208 .owner = THIS_MODULE,
209 }, 209 },
210 .probe = adp5520_led_probe, 210 .probe = adp5520_led_probe,
211 .remove = adp5520_led_remove, 211 .remove = adp5520_led_remove,
212 }; 212 };
213 213
214 module_platform_driver(adp5520_led_driver); 214 module_platform_driver(adp5520_led_driver);
215 215
216 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); 216 MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
217 MODULE_DESCRIPTION("LEDS ADP5520(01) Driver"); 217 MODULE_DESCRIPTION("LEDS ADP5520(01) Driver");
218 MODULE_LICENSE("GPL"); 218 MODULE_LICENSE("GPL");
219 MODULE_ALIAS("platform:adp5520-led"); 219 MODULE_ALIAS("platform:adp5520-led");
220 220
drivers/leds/leds-asic3.c
1 /* 1 /*
2 * Copyright (C) 2011 Paul Parsons <lost.distance@yahoo.com> 2 * Copyright (C) 2011 Paul Parsons <lost.distance@yahoo.com>
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation. 6 * published by the Free Software Foundation.
7 */ 7 */
8 8
9 #include <linux/kernel.h> 9 #include <linux/kernel.h>
10 #include <linux/init.h> 10 #include <linux/init.h>
11 #include <linux/platform_device.h> 11 #include <linux/platform_device.h>
12 #include <linux/leds.h> 12 #include <linux/leds.h>
13 #include <linux/slab.h> 13 #include <linux/slab.h>
14 14
15 #include <linux/mfd/asic3.h> 15 #include <linux/mfd/asic3.h>
16 #include <linux/mfd/core.h> 16 #include <linux/mfd/core.h>
17 #include <linux/module.h> 17 #include <linux/module.h>
18 18
19 /* 19 /*
20 * The HTC ASIC3 LED GPIOs are inputs, not outputs. 20 * The HTC ASIC3 LED GPIOs are inputs, not outputs.
21 * Hence we turn the LEDs on/off via the TimeBase register. 21 * Hence we turn the LEDs on/off via the TimeBase register.
22 */ 22 */
23 23
24 /* 24 /*
25 * When TimeBase is 4 the clock resolution is about 32Hz. 25 * When TimeBase is 4 the clock resolution is about 32Hz.
26 * This driver supports hardware blinking with an on+off 26 * This driver supports hardware blinking with an on+off
27 * period from 62ms (2 clocks) to 125s (4000 clocks). 27 * period from 62ms (2 clocks) to 125s (4000 clocks).
28 */ 28 */
29 #define MS_TO_CLK(ms) DIV_ROUND_CLOSEST(((ms)*1024), 32000) 29 #define MS_TO_CLK(ms) DIV_ROUND_CLOSEST(((ms)*1024), 32000)
30 #define CLK_TO_MS(clk) (((clk)*32000)/1024) 30 #define CLK_TO_MS(clk) (((clk)*32000)/1024)
31 #define MAX_CLK 4000 /* Fits into 12-bit Time registers */ 31 #define MAX_CLK 4000 /* Fits into 12-bit Time registers */
32 #define MAX_MS CLK_TO_MS(MAX_CLK) 32 #define MAX_MS CLK_TO_MS(MAX_CLK)
33 33
34 static const unsigned int led_n_base[ASIC3_NUM_LEDS] = { 34 static const unsigned int led_n_base[ASIC3_NUM_LEDS] = {
35 [0] = ASIC3_LED_0_Base, 35 [0] = ASIC3_LED_0_Base,
36 [1] = ASIC3_LED_1_Base, 36 [1] = ASIC3_LED_1_Base,
37 [2] = ASIC3_LED_2_Base, 37 [2] = ASIC3_LED_2_Base,
38 }; 38 };
39 39
40 static void brightness_set(struct led_classdev *cdev, 40 static void brightness_set(struct led_classdev *cdev,
41 enum led_brightness value) 41 enum led_brightness value)
42 { 42 {
43 struct platform_device *pdev = to_platform_device(cdev->dev->parent); 43 struct platform_device *pdev = to_platform_device(cdev->dev->parent);
44 const struct mfd_cell *cell = mfd_get_cell(pdev); 44 const struct mfd_cell *cell = mfd_get_cell(pdev);
45 struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); 45 struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
46 u32 timebase; 46 u32 timebase;
47 unsigned int base; 47 unsigned int base;
48 48
49 timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4); 49 timebase = (value == LED_OFF) ? 0 : (LED_EN|0x4);
50 50
51 base = led_n_base[cell->id]; 51 base = led_n_base[cell->id];
52 asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32); 52 asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), 32);
53 asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32); 53 asic3_write_register(asic, (base + ASIC3_LED_DutyTime), 32);
54 asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0); 54 asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
55 asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase); 55 asic3_write_register(asic, (base + ASIC3_LED_TimeBase), timebase);
56 } 56 }
57 57
58 static int blink_set(struct led_classdev *cdev, 58 static int blink_set(struct led_classdev *cdev,
59 unsigned long *delay_on, 59 unsigned long *delay_on,
60 unsigned long *delay_off) 60 unsigned long *delay_off)
61 { 61 {
62 struct platform_device *pdev = to_platform_device(cdev->dev->parent); 62 struct platform_device *pdev = to_platform_device(cdev->dev->parent);
63 const struct mfd_cell *cell = mfd_get_cell(pdev); 63 const struct mfd_cell *cell = mfd_get_cell(pdev);
64 struct asic3 *asic = dev_get_drvdata(pdev->dev.parent); 64 struct asic3 *asic = dev_get_drvdata(pdev->dev.parent);
65 u32 on; 65 u32 on;
66 u32 off; 66 u32 off;
67 unsigned int base; 67 unsigned int base;
68 68
69 if (*delay_on > MAX_MS || *delay_off > MAX_MS) 69 if (*delay_on > MAX_MS || *delay_off > MAX_MS)
70 return -EINVAL; 70 return -EINVAL;
71 71
72 if (*delay_on == 0 && *delay_off == 0) { 72 if (*delay_on == 0 && *delay_off == 0) {
73 /* If both are zero then a sensible default should be chosen */ 73 /* If both are zero then a sensible default should be chosen */
74 on = MS_TO_CLK(500); 74 on = MS_TO_CLK(500);
75 off = MS_TO_CLK(500); 75 off = MS_TO_CLK(500);
76 } else { 76 } else {
77 on = MS_TO_CLK(*delay_on); 77 on = MS_TO_CLK(*delay_on);
78 off = MS_TO_CLK(*delay_off); 78 off = MS_TO_CLK(*delay_off);
79 if ((on + off) > MAX_CLK) 79 if ((on + off) > MAX_CLK)
80 return -EINVAL; 80 return -EINVAL;
81 } 81 }
82 82
83 base = led_n_base[cell->id]; 83 base = led_n_base[cell->id];
84 asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off)); 84 asic3_write_register(asic, (base + ASIC3_LED_PeriodTime), (on + off));
85 asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on); 85 asic3_write_register(asic, (base + ASIC3_LED_DutyTime), on);
86 asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0); 86 asic3_write_register(asic, (base + ASIC3_LED_AutoStopCount), 0);
87 asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4)); 87 asic3_write_register(asic, (base + ASIC3_LED_TimeBase), (LED_EN|0x4));
88 88
89 *delay_on = CLK_TO_MS(on); 89 *delay_on = CLK_TO_MS(on);
90 *delay_off = CLK_TO_MS(off); 90 *delay_off = CLK_TO_MS(off);
91 91
92 return 0; 92 return 0;
93 } 93 }
94 94
95 static int asic3_led_probe(struct platform_device *pdev) 95 static int asic3_led_probe(struct platform_device *pdev)
96 { 96 {
97 struct asic3_led *led = pdev->dev.platform_data; 97 struct asic3_led *led = dev_get_platdata(&pdev->dev);
98 int ret; 98 int ret;
99 99
100 ret = mfd_cell_enable(pdev); 100 ret = mfd_cell_enable(pdev);
101 if (ret < 0) 101 if (ret < 0)
102 return ret; 102 return ret;
103 103
104 led->cdev = devm_kzalloc(&pdev->dev, sizeof(struct led_classdev), 104 led->cdev = devm_kzalloc(&pdev->dev, sizeof(struct led_classdev),
105 GFP_KERNEL); 105 GFP_KERNEL);
106 if (!led->cdev) { 106 if (!led->cdev) {
107 ret = -ENOMEM; 107 ret = -ENOMEM;
108 goto out; 108 goto out;
109 } 109 }
110 110
111 led->cdev->name = led->name; 111 led->cdev->name = led->name;
112 led->cdev->flags = LED_CORE_SUSPENDRESUME; 112 led->cdev->flags = LED_CORE_SUSPENDRESUME;
113 led->cdev->brightness_set = brightness_set; 113 led->cdev->brightness_set = brightness_set;
114 led->cdev->blink_set = blink_set; 114 led->cdev->blink_set = blink_set;
115 led->cdev->default_trigger = led->default_trigger; 115 led->cdev->default_trigger = led->default_trigger;
116 116
117 ret = led_classdev_register(&pdev->dev, led->cdev); 117 ret = led_classdev_register(&pdev->dev, led->cdev);
118 if (ret < 0) 118 if (ret < 0)
119 goto out; 119 goto out;
120 120
121 return 0; 121 return 0;
122 122
123 out: 123 out:
124 (void) mfd_cell_disable(pdev); 124 (void) mfd_cell_disable(pdev);
125 return ret; 125 return ret;
126 } 126 }
127 127
128 static int asic3_led_remove(struct platform_device *pdev) 128 static int asic3_led_remove(struct platform_device *pdev)
129 { 129 {
130 struct asic3_led *led = pdev->dev.platform_data; 130 struct asic3_led *led = dev_get_platdata(&pdev->dev);
131 131
132 led_classdev_unregister(led->cdev); 132 led_classdev_unregister(led->cdev);
133 133
134 return mfd_cell_disable(pdev); 134 return mfd_cell_disable(pdev);
135 } 135 }
136 136
137 #ifdef CONFIG_PM_SLEEP 137 #ifdef CONFIG_PM_SLEEP
138 static int asic3_led_suspend(struct device *dev) 138 static int asic3_led_suspend(struct device *dev)
139 { 139 {
140 struct platform_device *pdev = to_platform_device(dev); 140 struct platform_device *pdev = to_platform_device(dev);
141 const struct mfd_cell *cell = mfd_get_cell(pdev); 141 const struct mfd_cell *cell = mfd_get_cell(pdev);
142 int ret; 142 int ret;
143 143
144 ret = 0; 144 ret = 0;
145 if (cell->suspend) 145 if (cell->suspend)
146 ret = (*cell->suspend)(pdev); 146 ret = (*cell->suspend)(pdev);
147 147
148 return ret; 148 return ret;
149 } 149 }
150 150
151 static int asic3_led_resume(struct device *dev) 151 static int asic3_led_resume(struct device *dev)
152 { 152 {
153 struct platform_device *pdev = to_platform_device(dev); 153 struct platform_device *pdev = to_platform_device(dev);
154 const struct mfd_cell *cell = mfd_get_cell(pdev); 154 const struct mfd_cell *cell = mfd_get_cell(pdev);
155 int ret; 155 int ret;
156 156
157 ret = 0; 157 ret = 0;
158 if (cell->resume) 158 if (cell->resume)
159 ret = (*cell->resume)(pdev); 159 ret = (*cell->resume)(pdev);
160 160
161 return ret; 161 return ret;
162 } 162 }
163 #endif 163 #endif
164 164
165 static SIMPLE_DEV_PM_OPS(asic3_led_pm_ops, asic3_led_suspend, asic3_led_resume); 165 static SIMPLE_DEV_PM_OPS(asic3_led_pm_ops, asic3_led_suspend, asic3_led_resume);
166 166
167 static struct platform_driver asic3_led_driver = { 167 static struct platform_driver asic3_led_driver = {
168 .probe = asic3_led_probe, 168 .probe = asic3_led_probe,
169 .remove = asic3_led_remove, 169 .remove = asic3_led_remove,
170 .driver = { 170 .driver = {
171 .name = "leds-asic3", 171 .name = "leds-asic3",
172 .owner = THIS_MODULE, 172 .owner = THIS_MODULE,
173 .pm = &asic3_led_pm_ops, 173 .pm = &asic3_led_pm_ops,
174 }, 174 },
175 }; 175 };
176 176
177 module_platform_driver(asic3_led_driver); 177 module_platform_driver(asic3_led_driver);
178 178
179 MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>"); 179 MODULE_AUTHOR("Paul Parsons <lost.distance@yahoo.com>");
180 MODULE_DESCRIPTION("HTC ASIC3 LED driver"); 180 MODULE_DESCRIPTION("HTC ASIC3 LED driver");
181 MODULE_LICENSE("GPL"); 181 MODULE_LICENSE("GPL");
182 MODULE_ALIAS("platform:leds-asic3"); 182 MODULE_ALIAS("platform:leds-asic3");
183 183
drivers/leds/leds-atmel-pwm.c
1 #include <linux/kernel.h> 1 #include <linux/kernel.h>
2 #include <linux/platform_device.h> 2 #include <linux/platform_device.h>
3 #include <linux/leds.h> 3 #include <linux/leds.h>
4 #include <linux/io.h> 4 #include <linux/io.h>
5 #include <linux/atmel_pwm.h> 5 #include <linux/atmel_pwm.h>
6 #include <linux/slab.h> 6 #include <linux/slab.h>
7 #include <linux/module.h> 7 #include <linux/module.h>
8 8
9 9
10 struct pwmled { 10 struct pwmled {
11 struct led_classdev cdev; 11 struct led_classdev cdev;
12 struct pwm_channel pwmc; 12 struct pwm_channel pwmc;
13 struct gpio_led *desc; 13 struct gpio_led *desc;
14 u32 mult; 14 u32 mult;
15 u8 active_low; 15 u8 active_low;
16 }; 16 };
17 17
18 18
19 /* 19 /*
20 * For simplicity, we use "brightness" as if it were a linear function 20 * For simplicity, we use "brightness" as if it were a linear function
21 * of PWM duty cycle. However, a logarithmic function of duty cycle is 21 * of PWM duty cycle. However, a logarithmic function of duty cycle is
22 * probably a better match for perceived brightness: two is half as bright 22 * probably a better match for perceived brightness: two is half as bright
23 * as four, four is half as bright as eight, etc 23 * as four, four is half as bright as eight, etc
24 */ 24 */
25 static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b) 25 static void pwmled_brightness(struct led_classdev *cdev, enum led_brightness b)
26 { 26 {
27 struct pwmled *led; 27 struct pwmled *led;
28 28
29 /* update the duty cycle for the *next* period */ 29 /* update the duty cycle for the *next* period */
30 led = container_of(cdev, struct pwmled, cdev); 30 led = container_of(cdev, struct pwmled, cdev);
31 pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b); 31 pwm_channel_writel(&led->pwmc, PWM_CUPD, led->mult * (unsigned) b);
32 } 32 }
33 33
34 /* 34 /*
35 * NOTE: we reuse the platform_data structure of GPIO leds, 35 * NOTE: we reuse the platform_data structure of GPIO leds,
36 * but repurpose its "gpio" number as a PWM channel number. 36 * but repurpose its "gpio" number as a PWM channel number.
37 */ 37 */
38 static int pwmled_probe(struct platform_device *pdev) 38 static int pwmled_probe(struct platform_device *pdev)
39 { 39 {
40 const struct gpio_led_platform_data *pdata; 40 const struct gpio_led_platform_data *pdata;
41 struct pwmled *leds; 41 struct pwmled *leds;
42 int i; 42 int i;
43 int status; 43 int status;
44 44
45 pdata = pdev->dev.platform_data; 45 pdata = dev_get_platdata(&pdev->dev);
46 if (!pdata || pdata->num_leds < 1) 46 if (!pdata || pdata->num_leds < 1)
47 return -ENODEV; 47 return -ENODEV;
48 48
49 leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds), 49 leds = devm_kzalloc(&pdev->dev, pdata->num_leds * sizeof(*leds),
50 GFP_KERNEL); 50 GFP_KERNEL);
51 if (!leds) 51 if (!leds)
52 return -ENOMEM; 52 return -ENOMEM;
53 53
54 for (i = 0; i < pdata->num_leds; i++) { 54 for (i = 0; i < pdata->num_leds; i++) {
55 struct pwmled *led = leds + i; 55 struct pwmled *led = leds + i;
56 const struct gpio_led *dat = pdata->leds + i; 56 const struct gpio_led *dat = pdata->leds + i;
57 u32 tmp; 57 u32 tmp;
58 58
59 led->cdev.name = dat->name; 59 led->cdev.name = dat->name;
60 led->cdev.brightness = LED_OFF; 60 led->cdev.brightness = LED_OFF;
61 led->cdev.brightness_set = pwmled_brightness; 61 led->cdev.brightness_set = pwmled_brightness;
62 led->cdev.default_trigger = dat->default_trigger; 62 led->cdev.default_trigger = dat->default_trigger;
63 63
64 led->active_low = dat->active_low; 64 led->active_low = dat->active_low;
65 65
66 status = pwm_channel_alloc(dat->gpio, &led->pwmc); 66 status = pwm_channel_alloc(dat->gpio, &led->pwmc);
67 if (status < 0) 67 if (status < 0)
68 goto err; 68 goto err;
69 69
70 /* 70 /*
71 * Prescale clock by 2^x, so PWM counts in low MHz. 71 * Prescale clock by 2^x, so PWM counts in low MHz.
72 * Start each cycle with the LED active, so increasing 72 * Start each cycle with the LED active, so increasing
73 * the duty cycle gives us more time on (== brighter). 73 * the duty cycle gives us more time on (== brighter).
74 */ 74 */
75 tmp = 5; 75 tmp = 5;
76 if (!led->active_low) 76 if (!led->active_low)
77 tmp |= PWM_CPR_CPOL; 77 tmp |= PWM_CPR_CPOL;
78 pwm_channel_writel(&led->pwmc, PWM_CMR, tmp); 78 pwm_channel_writel(&led->pwmc, PWM_CMR, tmp);
79 79
80 /* 80 /*
81 * Pick a period so PWM cycles at 100+ Hz; and a multiplier 81 * Pick a period so PWM cycles at 100+ Hz; and a multiplier
82 * for scaling duty cycle: brightness * mult. 82 * for scaling duty cycle: brightness * mult.
83 */ 83 */
84 tmp = (led->pwmc.mck / (1 << 5)) / 100; 84 tmp = (led->pwmc.mck / (1 << 5)) / 100;
85 tmp /= 255; 85 tmp /= 255;
86 led->mult = tmp; 86 led->mult = tmp;
87 pwm_channel_writel(&led->pwmc, PWM_CDTY, 87 pwm_channel_writel(&led->pwmc, PWM_CDTY,
88 led->cdev.brightness * 255); 88 led->cdev.brightness * 255);
89 pwm_channel_writel(&led->pwmc, PWM_CPRD, 89 pwm_channel_writel(&led->pwmc, PWM_CPRD,
90 LED_FULL * tmp); 90 LED_FULL * tmp);
91 91
92 pwm_channel_enable(&led->pwmc); 92 pwm_channel_enable(&led->pwmc);
93 93
94 /* Hand it over to the LED framework */ 94 /* Hand it over to the LED framework */
95 status = led_classdev_register(&pdev->dev, &led->cdev); 95 status = led_classdev_register(&pdev->dev, &led->cdev);
96 if (status < 0) { 96 if (status < 0) {
97 pwm_channel_free(&led->pwmc); 97 pwm_channel_free(&led->pwmc);
98 goto err; 98 goto err;
99 } 99 }
100 } 100 }
101 101
102 platform_set_drvdata(pdev, leds); 102 platform_set_drvdata(pdev, leds);
103 return 0; 103 return 0;
104 104
105 err: 105 err:
106 if (i > 0) { 106 if (i > 0) {
107 for (i = i - 1; i >= 0; i--) { 107 for (i = i - 1; i >= 0; i--) {
108 led_classdev_unregister(&leds[i].cdev); 108 led_classdev_unregister(&leds[i].cdev);
109 pwm_channel_free(&leds[i].pwmc); 109 pwm_channel_free(&leds[i].pwmc);
110 } 110 }
111 } 111 }
112 112
113 return status; 113 return status;
114 } 114 }
115 115
116 static int pwmled_remove(struct platform_device *pdev) 116 static int pwmled_remove(struct platform_device *pdev)
117 { 117 {
118 const struct gpio_led_platform_data *pdata; 118 const struct gpio_led_platform_data *pdata;
119 struct pwmled *leds; 119 struct pwmled *leds;
120 unsigned i; 120 unsigned i;
121 121
122 pdata = pdev->dev.platform_data; 122 pdata = dev_get_platdata(&pdev->dev);
123 leds = platform_get_drvdata(pdev); 123 leds = platform_get_drvdata(pdev);
124 124
125 for (i = 0; i < pdata->num_leds; i++) { 125 for (i = 0; i < pdata->num_leds; i++) {
126 struct pwmled *led = leds + i; 126 struct pwmled *led = leds + i;
127 127
128 led_classdev_unregister(&led->cdev); 128 led_classdev_unregister(&led->cdev);
129 pwm_channel_free(&led->pwmc); 129 pwm_channel_free(&led->pwmc);
130 } 130 }
131 131
132 return 0; 132 return 0;
133 } 133 }
134 134
135 static struct platform_driver pwmled_driver = { 135 static struct platform_driver pwmled_driver = {
136 .driver = { 136 .driver = {
137 .name = "leds-atmel-pwm", 137 .name = "leds-atmel-pwm",
138 .owner = THIS_MODULE, 138 .owner = THIS_MODULE,
139 }, 139 },
140 /* REVISIT add suspend() and resume() methods */ 140 /* REVISIT add suspend() and resume() methods */
141 .probe = pwmled_probe, 141 .probe = pwmled_probe,
142 .remove = pwmled_remove, 142 .remove = pwmled_remove,
143 }; 143 };
144 144
145 module_platform_driver(pwmled_driver); 145 module_platform_driver(pwmled_driver);
146 146
147 MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness"); 147 MODULE_DESCRIPTION("Driver for LEDs with PWM-controlled brightness");
148 MODULE_LICENSE("GPL"); 148 MODULE_LICENSE("GPL");
149 MODULE_ALIAS("platform:leds-atmel-pwm"); 149 MODULE_ALIAS("platform:leds-atmel-pwm");
150 150
drivers/leds/leds-bd2802.c
1 /* 1 /*
2 * leds-bd2802.c - RGB LED Driver 2 * leds-bd2802.c - RGB LED Driver
3 * 3 *
4 * Copyright (C) 2009 Samsung Electronics 4 * Copyright (C) 2009 Samsung Electronics
5 * Kim Kyuwon <q1.kim@samsung.com> 5 * Kim Kyuwon <q1.kim@samsung.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 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 8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 * 10 *
11 * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf 11 * Datasheet: http://www.rohm.com/products/databook/driver/pdf/bd2802gu-e.pdf
12 * 12 *
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/i2c.h> 16 #include <linux/i2c.h>
17 #include <linux/gpio.h> 17 #include <linux/gpio.h>
18 #include <linux/delay.h> 18 #include <linux/delay.h>
19 #include <linux/leds.h> 19 #include <linux/leds.h>
20 #include <linux/leds-bd2802.h> 20 #include <linux/leds-bd2802.h>
21 #include <linux/slab.h> 21 #include <linux/slab.h>
22 #include <linux/pm.h> 22 #include <linux/pm.h>
23 23
24 #define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0)) 24 #define LED_CTL(rgb2en, rgb1en) ((rgb2en) << 4 | ((rgb1en) << 0))
25 25
26 #define BD2802_LED_OFFSET 0xa 26 #define BD2802_LED_OFFSET 0xa
27 #define BD2802_COLOR_OFFSET 0x3 27 #define BD2802_COLOR_OFFSET 0x3
28 28
29 #define BD2802_REG_CLKSETUP 0x00 29 #define BD2802_REG_CLKSETUP 0x00
30 #define BD2802_REG_CONTROL 0x01 30 #define BD2802_REG_CONTROL 0x01
31 #define BD2802_REG_HOURSETUP 0x02 31 #define BD2802_REG_HOURSETUP 0x02
32 #define BD2802_REG_CURRENT1SETUP 0x03 32 #define BD2802_REG_CURRENT1SETUP 0x03
33 #define BD2802_REG_CURRENT2SETUP 0x04 33 #define BD2802_REG_CURRENT2SETUP 0x04
34 #define BD2802_REG_WAVEPATTERN 0x05 34 #define BD2802_REG_WAVEPATTERN 0x05
35 35
36 #define BD2802_CURRENT_032 0x10 /* 3.2mA */ 36 #define BD2802_CURRENT_032 0x10 /* 3.2mA */
37 #define BD2802_CURRENT_000 0x00 /* 0.0mA */ 37 #define BD2802_CURRENT_000 0x00 /* 0.0mA */
38 38
39 #define BD2802_PATTERN_FULL 0x07 39 #define BD2802_PATTERN_FULL 0x07
40 #define BD2802_PATTERN_HALF 0x03 40 #define BD2802_PATTERN_HALF 0x03
41 41
42 enum led_ids { 42 enum led_ids {
43 LED1, 43 LED1,
44 LED2, 44 LED2,
45 LED_NUM, 45 LED_NUM,
46 }; 46 };
47 47
48 enum led_colors { 48 enum led_colors {
49 RED, 49 RED,
50 GREEN, 50 GREEN,
51 BLUE, 51 BLUE,
52 }; 52 };
53 53
54 enum led_bits { 54 enum led_bits {
55 BD2802_OFF, 55 BD2802_OFF,
56 BD2802_BLINK, 56 BD2802_BLINK,
57 BD2802_ON, 57 BD2802_ON,
58 }; 58 };
59 59
60 /* 60 /*
61 * State '0' : 'off' 61 * State '0' : 'off'
62 * State '1' : 'blink' 62 * State '1' : 'blink'
63 * State '2' : 'on'. 63 * State '2' : 'on'.
64 */ 64 */
65 struct led_state { 65 struct led_state {
66 unsigned r:2; 66 unsigned r:2;
67 unsigned g:2; 67 unsigned g:2;
68 unsigned b:2; 68 unsigned b:2;
69 }; 69 };
70 70
71 struct bd2802_led { 71 struct bd2802_led {
72 struct bd2802_led_platform_data *pdata; 72 struct bd2802_led_platform_data *pdata;
73 struct i2c_client *client; 73 struct i2c_client *client;
74 struct rw_semaphore rwsem; 74 struct rw_semaphore rwsem;
75 struct work_struct work; 75 struct work_struct work;
76 76
77 struct led_state led[2]; 77 struct led_state led[2];
78 78
79 /* 79 /*
80 * Making led_classdev as array is not recommended, because array 80 * Making led_classdev as array is not recommended, because array
81 * members prevent using 'container_of' macro. So repetitive works 81 * members prevent using 'container_of' macro. So repetitive works
82 * are needed. 82 * are needed.
83 */ 83 */
84 struct led_classdev cdev_led1r; 84 struct led_classdev cdev_led1r;
85 struct led_classdev cdev_led1g; 85 struct led_classdev cdev_led1g;
86 struct led_classdev cdev_led1b; 86 struct led_classdev cdev_led1b;
87 struct led_classdev cdev_led2r; 87 struct led_classdev cdev_led2r;
88 struct led_classdev cdev_led2g; 88 struct led_classdev cdev_led2g;
89 struct led_classdev cdev_led2b; 89 struct led_classdev cdev_led2b;
90 90
91 /* 91 /*
92 * Advanced Configuration Function(ADF) mode: 92 * Advanced Configuration Function(ADF) mode:
93 * In ADF mode, user can set registers of BD2802GU directly, 93 * In ADF mode, user can set registers of BD2802GU directly,
94 * therefore BD2802GU doesn't enter reset state. 94 * therefore BD2802GU doesn't enter reset state.
95 */ 95 */
96 int adf_on; 96 int adf_on;
97 97
98 enum led_ids led_id; 98 enum led_ids led_id;
99 enum led_colors color; 99 enum led_colors color;
100 enum led_bits state; 100 enum led_bits state;
101 101
102 /* General attributes of RGB LEDs */ 102 /* General attributes of RGB LEDs */
103 int wave_pattern; 103 int wave_pattern;
104 int rgb_current; 104 int rgb_current;
105 }; 105 };
106 106
107 107
108 /*--------------------------------------------------------------*/ 108 /*--------------------------------------------------------------*/
109 /* BD2802GU helper functions */ 109 /* BD2802GU helper functions */
110 /*--------------------------------------------------------------*/ 110 /*--------------------------------------------------------------*/
111 111
112 static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id, 112 static inline int bd2802_is_rgb_off(struct bd2802_led *led, enum led_ids id,
113 enum led_colors color) 113 enum led_colors color)
114 { 114 {
115 switch (color) { 115 switch (color) {
116 case RED: 116 case RED:
117 return !led->led[id].r; 117 return !led->led[id].r;
118 case GREEN: 118 case GREEN:
119 return !led->led[id].g; 119 return !led->led[id].g;
120 case BLUE: 120 case BLUE:
121 return !led->led[id].b; 121 return !led->led[id].b;
122 default: 122 default:
123 dev_err(&led->client->dev, "%s: Invalid color\n", __func__); 123 dev_err(&led->client->dev, "%s: Invalid color\n", __func__);
124 return -EINVAL; 124 return -EINVAL;
125 } 125 }
126 } 126 }
127 127
128 static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id) 128 static inline int bd2802_is_led_off(struct bd2802_led *led, enum led_ids id)
129 { 129 {
130 if (led->led[id].r || led->led[id].g || led->led[id].b) 130 if (led->led[id].r || led->led[id].g || led->led[id].b)
131 return 0; 131 return 0;
132 132
133 return 1; 133 return 1;
134 } 134 }
135 135
136 static inline int bd2802_is_all_off(struct bd2802_led *led) 136 static inline int bd2802_is_all_off(struct bd2802_led *led)
137 { 137 {
138 int i; 138 int i;
139 139
140 for (i = 0; i < LED_NUM; i++) 140 for (i = 0; i < LED_NUM; i++)
141 if (!bd2802_is_led_off(led, i)) 141 if (!bd2802_is_led_off(led, i))
142 return 0; 142 return 0;
143 143
144 return 1; 144 return 1;
145 } 145 }
146 146
147 static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color) 147 static inline u8 bd2802_get_base_offset(enum led_ids id, enum led_colors color)
148 { 148 {
149 return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET; 149 return id * BD2802_LED_OFFSET + color * BD2802_COLOR_OFFSET;
150 } 150 }
151 151
152 static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color, 152 static inline u8 bd2802_get_reg_addr(enum led_ids id, enum led_colors color,
153 u8 reg_offset) 153 u8 reg_offset)
154 { 154 {
155 return reg_offset + bd2802_get_base_offset(id, color); 155 return reg_offset + bd2802_get_base_offset(id, color);
156 } 156 }
157 157
158 158
159 /*--------------------------------------------------------------*/ 159 /*--------------------------------------------------------------*/
160 /* BD2802GU core functions */ 160 /* BD2802GU core functions */
161 /*--------------------------------------------------------------*/ 161 /*--------------------------------------------------------------*/
162 162
163 static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val) 163 static int bd2802_write_byte(struct i2c_client *client, u8 reg, u8 val)
164 { 164 {
165 int ret = i2c_smbus_write_byte_data(client, reg, val); 165 int ret = i2c_smbus_write_byte_data(client, reg, val);
166 if (ret >= 0) 166 if (ret >= 0)
167 return 0; 167 return 0;
168 168
169 dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n", 169 dev_err(&client->dev, "%s: reg 0x%x, val 0x%x, err %d\n",
170 __func__, reg, val, ret); 170 __func__, reg, val, ret);
171 171
172 return ret; 172 return ret;
173 } 173 }
174 174
175 static void bd2802_update_state(struct bd2802_led *led, enum led_ids id, 175 static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
176 enum led_colors color, enum led_bits led_bit) 176 enum led_colors color, enum led_bits led_bit)
177 { 177 {
178 int i; 178 int i;
179 u8 value; 179 u8 value;
180 180
181 for (i = 0; i < LED_NUM; i++) { 181 for (i = 0; i < LED_NUM; i++) {
182 if (i == id) { 182 if (i == id) {
183 switch (color) { 183 switch (color) {
184 case RED: 184 case RED:
185 led->led[i].r = led_bit; 185 led->led[i].r = led_bit;
186 break; 186 break;
187 case GREEN: 187 case GREEN:
188 led->led[i].g = led_bit; 188 led->led[i].g = led_bit;
189 break; 189 break;
190 case BLUE: 190 case BLUE:
191 led->led[i].b = led_bit; 191 led->led[i].b = led_bit;
192 break; 192 break;
193 default: 193 default:
194 dev_err(&led->client->dev, 194 dev_err(&led->client->dev,
195 "%s: Invalid color\n", __func__); 195 "%s: Invalid color\n", __func__);
196 return; 196 return;
197 } 197 }
198 } 198 }
199 } 199 }
200 200
201 if (led_bit == BD2802_BLINK || led_bit == BD2802_ON) 201 if (led_bit == BD2802_BLINK || led_bit == BD2802_ON)
202 return; 202 return;
203 203
204 if (!bd2802_is_led_off(led, id)) 204 if (!bd2802_is_led_off(led, id))
205 return; 205 return;
206 206
207 if (bd2802_is_all_off(led) && !led->adf_on) { 207 if (bd2802_is_all_off(led) && !led->adf_on) {
208 gpio_set_value(led->pdata->reset_gpio, 0); 208 gpio_set_value(led->pdata->reset_gpio, 0);
209 return; 209 return;
210 } 210 }
211 211
212 /* 212 /*
213 * In this case, other led is turned on, and current led is turned 213 * In this case, other led is turned on, and current led is turned
214 * off. So set RGB LED Control register to stop the current RGB LED 214 * off. So set RGB LED Control register to stop the current RGB LED
215 */ 215 */
216 value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1); 216 value = (id == LED1) ? LED_CTL(1, 0) : LED_CTL(0, 1);
217 bd2802_write_byte(led->client, BD2802_REG_CONTROL, value); 217 bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
218 } 218 }
219 219
220 static void bd2802_configure(struct bd2802_led *led) 220 static void bd2802_configure(struct bd2802_led *led)
221 { 221 {
222 struct bd2802_led_platform_data *pdata = led->pdata; 222 struct bd2802_led_platform_data *pdata = led->pdata;
223 u8 reg; 223 u8 reg;
224 224
225 reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP); 225 reg = bd2802_get_reg_addr(LED1, RED, BD2802_REG_HOURSETUP);
226 bd2802_write_byte(led->client, reg, pdata->rgb_time); 226 bd2802_write_byte(led->client, reg, pdata->rgb_time);
227 227
228 reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP); 228 reg = bd2802_get_reg_addr(LED2, RED, BD2802_REG_HOURSETUP);
229 bd2802_write_byte(led->client, reg, pdata->rgb_time); 229 bd2802_write_byte(led->client, reg, pdata->rgb_time);
230 } 230 }
231 231
232 static void bd2802_reset_cancel(struct bd2802_led *led) 232 static void bd2802_reset_cancel(struct bd2802_led *led)
233 { 233 {
234 gpio_set_value(led->pdata->reset_gpio, 1); 234 gpio_set_value(led->pdata->reset_gpio, 1);
235 udelay(100); 235 udelay(100);
236 bd2802_configure(led); 236 bd2802_configure(led);
237 } 237 }
238 238
239 static void bd2802_enable(struct bd2802_led *led, enum led_ids id) 239 static void bd2802_enable(struct bd2802_led *led, enum led_ids id)
240 { 240 {
241 enum led_ids other_led = (id == LED1) ? LED2 : LED1; 241 enum led_ids other_led = (id == LED1) ? LED2 : LED1;
242 u8 value, other_led_on; 242 u8 value, other_led_on;
243 243
244 other_led_on = !bd2802_is_led_off(led, other_led); 244 other_led_on = !bd2802_is_led_off(led, other_led);
245 if (id == LED1) 245 if (id == LED1)
246 value = LED_CTL(other_led_on, 1); 246 value = LED_CTL(other_led_on, 1);
247 else 247 else
248 value = LED_CTL(1 , other_led_on); 248 value = LED_CTL(1 , other_led_on);
249 249
250 bd2802_write_byte(led->client, BD2802_REG_CONTROL, value); 250 bd2802_write_byte(led->client, BD2802_REG_CONTROL, value);
251 } 251 }
252 252
253 static void bd2802_set_on(struct bd2802_led *led, enum led_ids id, 253 static void bd2802_set_on(struct bd2802_led *led, enum led_ids id,
254 enum led_colors color) 254 enum led_colors color)
255 { 255 {
256 u8 reg; 256 u8 reg;
257 257
258 if (bd2802_is_all_off(led) && !led->adf_on) 258 if (bd2802_is_all_off(led) && !led->adf_on)
259 bd2802_reset_cancel(led); 259 bd2802_reset_cancel(led);
260 260
261 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); 261 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
262 bd2802_write_byte(led->client, reg, led->rgb_current); 262 bd2802_write_byte(led->client, reg, led->rgb_current);
263 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); 263 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
264 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); 264 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
265 reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); 265 reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
266 bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL); 266 bd2802_write_byte(led->client, reg, BD2802_PATTERN_FULL);
267 267
268 bd2802_enable(led, id); 268 bd2802_enable(led, id);
269 bd2802_update_state(led, id, color, BD2802_ON); 269 bd2802_update_state(led, id, color, BD2802_ON);
270 } 270 }
271 271
272 static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id, 272 static void bd2802_set_blink(struct bd2802_led *led, enum led_ids id,
273 enum led_colors color) 273 enum led_colors color)
274 { 274 {
275 u8 reg; 275 u8 reg;
276 276
277 if (bd2802_is_all_off(led) && !led->adf_on) 277 if (bd2802_is_all_off(led) && !led->adf_on)
278 bd2802_reset_cancel(led); 278 bd2802_reset_cancel(led);
279 279
280 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); 280 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
281 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); 281 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
282 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); 282 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
283 bd2802_write_byte(led->client, reg, led->rgb_current); 283 bd2802_write_byte(led->client, reg, led->rgb_current);
284 reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN); 284 reg = bd2802_get_reg_addr(id, color, BD2802_REG_WAVEPATTERN);
285 bd2802_write_byte(led->client, reg, led->wave_pattern); 285 bd2802_write_byte(led->client, reg, led->wave_pattern);
286 286
287 bd2802_enable(led, id); 287 bd2802_enable(led, id);
288 bd2802_update_state(led, id, color, BD2802_BLINK); 288 bd2802_update_state(led, id, color, BD2802_BLINK);
289 } 289 }
290 290
291 static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id, 291 static void bd2802_turn_on(struct bd2802_led *led, enum led_ids id,
292 enum led_colors color, enum led_bits led_bit) 292 enum led_colors color, enum led_bits led_bit)
293 { 293 {
294 if (led_bit == BD2802_OFF) { 294 if (led_bit == BD2802_OFF) {
295 dev_err(&led->client->dev, 295 dev_err(&led->client->dev,
296 "Only 'blink' and 'on' are allowed\n"); 296 "Only 'blink' and 'on' are allowed\n");
297 return; 297 return;
298 } 298 }
299 299
300 if (led_bit == BD2802_BLINK) 300 if (led_bit == BD2802_BLINK)
301 bd2802_set_blink(led, id, color); 301 bd2802_set_blink(led, id, color);
302 else 302 else
303 bd2802_set_on(led, id, color); 303 bd2802_set_on(led, id, color);
304 } 304 }
305 305
306 static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id, 306 static void bd2802_turn_off(struct bd2802_led *led, enum led_ids id,
307 enum led_colors color) 307 enum led_colors color)
308 { 308 {
309 u8 reg; 309 u8 reg;
310 310
311 if (bd2802_is_rgb_off(led, id, color)) 311 if (bd2802_is_rgb_off(led, id, color))
312 return; 312 return;
313 313
314 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP); 314 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT1SETUP);
315 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); 315 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
316 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP); 316 reg = bd2802_get_reg_addr(id, color, BD2802_REG_CURRENT2SETUP);
317 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000); 317 bd2802_write_byte(led->client, reg, BD2802_CURRENT_000);
318 318
319 bd2802_update_state(led, id, color, BD2802_OFF); 319 bd2802_update_state(led, id, color, BD2802_OFF);
320 } 320 }
321 321
322 #define BD2802_SET_REGISTER(reg_addr, reg_name) \ 322 #define BD2802_SET_REGISTER(reg_addr, reg_name) \
323 static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \ 323 static ssize_t bd2802_store_reg##reg_addr(struct device *dev, \
324 struct device_attribute *attr, const char *buf, size_t count) \ 324 struct device_attribute *attr, const char *buf, size_t count) \
325 { \ 325 { \
326 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ 326 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
327 unsigned long val; \ 327 unsigned long val; \
328 int ret; \ 328 int ret; \
329 if (!count) \ 329 if (!count) \
330 return -EINVAL; \ 330 return -EINVAL; \
331 ret = kstrtoul(buf, 16, &val); \ 331 ret = kstrtoul(buf, 16, &val); \
332 if (ret) \ 332 if (ret) \
333 return ret; \ 333 return ret; \
334 down_write(&led->rwsem); \ 334 down_write(&led->rwsem); \
335 bd2802_write_byte(led->client, reg_addr, (u8) val); \ 335 bd2802_write_byte(led->client, reg_addr, (u8) val); \
336 up_write(&led->rwsem); \ 336 up_write(&led->rwsem); \
337 return count; \ 337 return count; \
338 } \ 338 } \
339 static struct device_attribute bd2802_reg##reg_addr##_attr = { \ 339 static struct device_attribute bd2802_reg##reg_addr##_attr = { \
340 .attr = {.name = reg_name, .mode = 0644}, \ 340 .attr = {.name = reg_name, .mode = 0644}, \
341 .store = bd2802_store_reg##reg_addr, \ 341 .store = bd2802_store_reg##reg_addr, \
342 }; 342 };
343 343
344 BD2802_SET_REGISTER(0x00, "0x00"); 344 BD2802_SET_REGISTER(0x00, "0x00");
345 BD2802_SET_REGISTER(0x01, "0x01"); 345 BD2802_SET_REGISTER(0x01, "0x01");
346 BD2802_SET_REGISTER(0x02, "0x02"); 346 BD2802_SET_REGISTER(0x02, "0x02");
347 BD2802_SET_REGISTER(0x03, "0x03"); 347 BD2802_SET_REGISTER(0x03, "0x03");
348 BD2802_SET_REGISTER(0x04, "0x04"); 348 BD2802_SET_REGISTER(0x04, "0x04");
349 BD2802_SET_REGISTER(0x05, "0x05"); 349 BD2802_SET_REGISTER(0x05, "0x05");
350 BD2802_SET_REGISTER(0x06, "0x06"); 350 BD2802_SET_REGISTER(0x06, "0x06");
351 BD2802_SET_REGISTER(0x07, "0x07"); 351 BD2802_SET_REGISTER(0x07, "0x07");
352 BD2802_SET_REGISTER(0x08, "0x08"); 352 BD2802_SET_REGISTER(0x08, "0x08");
353 BD2802_SET_REGISTER(0x09, "0x09"); 353 BD2802_SET_REGISTER(0x09, "0x09");
354 BD2802_SET_REGISTER(0x0a, "0x0a"); 354 BD2802_SET_REGISTER(0x0a, "0x0a");
355 BD2802_SET_REGISTER(0x0b, "0x0b"); 355 BD2802_SET_REGISTER(0x0b, "0x0b");
356 BD2802_SET_REGISTER(0x0c, "0x0c"); 356 BD2802_SET_REGISTER(0x0c, "0x0c");
357 BD2802_SET_REGISTER(0x0d, "0x0d"); 357 BD2802_SET_REGISTER(0x0d, "0x0d");
358 BD2802_SET_REGISTER(0x0e, "0x0e"); 358 BD2802_SET_REGISTER(0x0e, "0x0e");
359 BD2802_SET_REGISTER(0x0f, "0x0f"); 359 BD2802_SET_REGISTER(0x0f, "0x0f");
360 BD2802_SET_REGISTER(0x10, "0x10"); 360 BD2802_SET_REGISTER(0x10, "0x10");
361 BD2802_SET_REGISTER(0x11, "0x11"); 361 BD2802_SET_REGISTER(0x11, "0x11");
362 BD2802_SET_REGISTER(0x12, "0x12"); 362 BD2802_SET_REGISTER(0x12, "0x12");
363 BD2802_SET_REGISTER(0x13, "0x13"); 363 BD2802_SET_REGISTER(0x13, "0x13");
364 BD2802_SET_REGISTER(0x14, "0x14"); 364 BD2802_SET_REGISTER(0x14, "0x14");
365 BD2802_SET_REGISTER(0x15, "0x15"); 365 BD2802_SET_REGISTER(0x15, "0x15");
366 366
367 static struct device_attribute *bd2802_addr_attributes[] = { 367 static struct device_attribute *bd2802_addr_attributes[] = {
368 &bd2802_reg0x00_attr, 368 &bd2802_reg0x00_attr,
369 &bd2802_reg0x01_attr, 369 &bd2802_reg0x01_attr,
370 &bd2802_reg0x02_attr, 370 &bd2802_reg0x02_attr,
371 &bd2802_reg0x03_attr, 371 &bd2802_reg0x03_attr,
372 &bd2802_reg0x04_attr, 372 &bd2802_reg0x04_attr,
373 &bd2802_reg0x05_attr, 373 &bd2802_reg0x05_attr,
374 &bd2802_reg0x06_attr, 374 &bd2802_reg0x06_attr,
375 &bd2802_reg0x07_attr, 375 &bd2802_reg0x07_attr,
376 &bd2802_reg0x08_attr, 376 &bd2802_reg0x08_attr,
377 &bd2802_reg0x09_attr, 377 &bd2802_reg0x09_attr,
378 &bd2802_reg0x0a_attr, 378 &bd2802_reg0x0a_attr,
379 &bd2802_reg0x0b_attr, 379 &bd2802_reg0x0b_attr,
380 &bd2802_reg0x0c_attr, 380 &bd2802_reg0x0c_attr,
381 &bd2802_reg0x0d_attr, 381 &bd2802_reg0x0d_attr,
382 &bd2802_reg0x0e_attr, 382 &bd2802_reg0x0e_attr,
383 &bd2802_reg0x0f_attr, 383 &bd2802_reg0x0f_attr,
384 &bd2802_reg0x10_attr, 384 &bd2802_reg0x10_attr,
385 &bd2802_reg0x11_attr, 385 &bd2802_reg0x11_attr,
386 &bd2802_reg0x12_attr, 386 &bd2802_reg0x12_attr,
387 &bd2802_reg0x13_attr, 387 &bd2802_reg0x13_attr,
388 &bd2802_reg0x14_attr, 388 &bd2802_reg0x14_attr,
389 &bd2802_reg0x15_attr, 389 &bd2802_reg0x15_attr,
390 }; 390 };
391 391
392 static void bd2802_enable_adv_conf(struct bd2802_led *led) 392 static void bd2802_enable_adv_conf(struct bd2802_led *led)
393 { 393 {
394 int i, ret; 394 int i, ret;
395 395
396 for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) { 396 for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) {
397 ret = device_create_file(&led->client->dev, 397 ret = device_create_file(&led->client->dev,
398 bd2802_addr_attributes[i]); 398 bd2802_addr_attributes[i]);
399 if (ret) { 399 if (ret) {
400 dev_err(&led->client->dev, "failed: sysfs file %s\n", 400 dev_err(&led->client->dev, "failed: sysfs file %s\n",
401 bd2802_addr_attributes[i]->attr.name); 401 bd2802_addr_attributes[i]->attr.name);
402 goto failed_remove_files; 402 goto failed_remove_files;
403 } 403 }
404 } 404 }
405 405
406 if (bd2802_is_all_off(led)) 406 if (bd2802_is_all_off(led))
407 bd2802_reset_cancel(led); 407 bd2802_reset_cancel(led);
408 408
409 led->adf_on = 1; 409 led->adf_on = 1;
410 410
411 return; 411 return;
412 412
413 failed_remove_files: 413 failed_remove_files:
414 for (i--; i >= 0; i--) 414 for (i--; i >= 0; i--)
415 device_remove_file(&led->client->dev, 415 device_remove_file(&led->client->dev,
416 bd2802_addr_attributes[i]); 416 bd2802_addr_attributes[i]);
417 } 417 }
418 418
419 static void bd2802_disable_adv_conf(struct bd2802_led *led) 419 static void bd2802_disable_adv_conf(struct bd2802_led *led)
420 { 420 {
421 int i; 421 int i;
422 422
423 for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++) 423 for (i = 0; i < ARRAY_SIZE(bd2802_addr_attributes); i++)
424 device_remove_file(&led->client->dev, 424 device_remove_file(&led->client->dev,
425 bd2802_addr_attributes[i]); 425 bd2802_addr_attributes[i]);
426 426
427 if (bd2802_is_all_off(led)) 427 if (bd2802_is_all_off(led))
428 gpio_set_value(led->pdata->reset_gpio, 0); 428 gpio_set_value(led->pdata->reset_gpio, 0);
429 429
430 led->adf_on = 0; 430 led->adf_on = 0;
431 } 431 }
432 432
433 static ssize_t bd2802_show_adv_conf(struct device *dev, 433 static ssize_t bd2802_show_adv_conf(struct device *dev,
434 struct device_attribute *attr, char *buf) 434 struct device_attribute *attr, char *buf)
435 { 435 {
436 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev)); 436 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
437 ssize_t ret; 437 ssize_t ret;
438 438
439 down_read(&led->rwsem); 439 down_read(&led->rwsem);
440 if (led->adf_on) 440 if (led->adf_on)
441 ret = sprintf(buf, "on\n"); 441 ret = sprintf(buf, "on\n");
442 else 442 else
443 ret = sprintf(buf, "off\n"); 443 ret = sprintf(buf, "off\n");
444 up_read(&led->rwsem); 444 up_read(&led->rwsem);
445 445
446 return ret; 446 return ret;
447 } 447 }
448 448
449 static ssize_t bd2802_store_adv_conf(struct device *dev, 449 static ssize_t bd2802_store_adv_conf(struct device *dev,
450 struct device_attribute *attr, const char *buf, size_t count) 450 struct device_attribute *attr, const char *buf, size_t count)
451 { 451 {
452 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev)); 452 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));
453 453
454 if (!count) 454 if (!count)
455 return -EINVAL; 455 return -EINVAL;
456 456
457 down_write(&led->rwsem); 457 down_write(&led->rwsem);
458 if (!led->adf_on && !strncmp(buf, "on", 2)) 458 if (!led->adf_on && !strncmp(buf, "on", 2))
459 bd2802_enable_adv_conf(led); 459 bd2802_enable_adv_conf(led);
460 else if (led->adf_on && !strncmp(buf, "off", 3)) 460 else if (led->adf_on && !strncmp(buf, "off", 3))
461 bd2802_disable_adv_conf(led); 461 bd2802_disable_adv_conf(led);
462 up_write(&led->rwsem); 462 up_write(&led->rwsem);
463 463
464 return count; 464 return count;
465 } 465 }
466 466
467 static struct device_attribute bd2802_adv_conf_attr = { 467 static struct device_attribute bd2802_adv_conf_attr = {
468 .attr = { 468 .attr = {
469 .name = "advanced_configuration", 469 .name = "advanced_configuration",
470 .mode = 0644, 470 .mode = 0644,
471 }, 471 },
472 .show = bd2802_show_adv_conf, 472 .show = bd2802_show_adv_conf,
473 .store = bd2802_store_adv_conf, 473 .store = bd2802_store_adv_conf,
474 }; 474 };
475 475
476 #define BD2802_CONTROL_ATTR(attr_name, name_str) \ 476 #define BD2802_CONTROL_ATTR(attr_name, name_str) \
477 static ssize_t bd2802_show_##attr_name(struct device *dev, \ 477 static ssize_t bd2802_show_##attr_name(struct device *dev, \
478 struct device_attribute *attr, char *buf) \ 478 struct device_attribute *attr, char *buf) \
479 { \ 479 { \
480 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ 480 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
481 ssize_t ret; \ 481 ssize_t ret; \
482 down_read(&led->rwsem); \ 482 down_read(&led->rwsem); \
483 ret = sprintf(buf, "0x%02x\n", led->attr_name); \ 483 ret = sprintf(buf, "0x%02x\n", led->attr_name); \
484 up_read(&led->rwsem); \ 484 up_read(&led->rwsem); \
485 return ret; \ 485 return ret; \
486 } \ 486 } \
487 static ssize_t bd2802_store_##attr_name(struct device *dev, \ 487 static ssize_t bd2802_store_##attr_name(struct device *dev, \
488 struct device_attribute *attr, const char *buf, size_t count) \ 488 struct device_attribute *attr, const char *buf, size_t count) \
489 { \ 489 { \
490 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\ 490 struct bd2802_led *led = i2c_get_clientdata(to_i2c_client(dev));\
491 unsigned long val; \ 491 unsigned long val; \
492 int ret; \ 492 int ret; \
493 if (!count) \ 493 if (!count) \
494 return -EINVAL; \ 494 return -EINVAL; \
495 ret = kstrtoul(buf, 16, &val); \ 495 ret = kstrtoul(buf, 16, &val); \
496 if (ret) \ 496 if (ret) \
497 return ret; \ 497 return ret; \
498 down_write(&led->rwsem); \ 498 down_write(&led->rwsem); \
499 led->attr_name = val; \ 499 led->attr_name = val; \
500 up_write(&led->rwsem); \ 500 up_write(&led->rwsem); \
501 return count; \ 501 return count; \
502 } \ 502 } \
503 static struct device_attribute bd2802_##attr_name##_attr = { \ 503 static struct device_attribute bd2802_##attr_name##_attr = { \
504 .attr = { \ 504 .attr = { \
505 .name = name_str, \ 505 .name = name_str, \
506 .mode = 0644, \ 506 .mode = 0644, \
507 }, \ 507 }, \
508 .show = bd2802_show_##attr_name, \ 508 .show = bd2802_show_##attr_name, \
509 .store = bd2802_store_##attr_name, \ 509 .store = bd2802_store_##attr_name, \
510 }; 510 };
511 511
512 BD2802_CONTROL_ATTR(wave_pattern, "wave_pattern"); 512 BD2802_CONTROL_ATTR(wave_pattern, "wave_pattern");
513 BD2802_CONTROL_ATTR(rgb_current, "rgb_current"); 513 BD2802_CONTROL_ATTR(rgb_current, "rgb_current");
514 514
515 static struct device_attribute *bd2802_attributes[] = { 515 static struct device_attribute *bd2802_attributes[] = {
516 &bd2802_adv_conf_attr, 516 &bd2802_adv_conf_attr,
517 &bd2802_wave_pattern_attr, 517 &bd2802_wave_pattern_attr,
518 &bd2802_rgb_current_attr, 518 &bd2802_rgb_current_attr,
519 }; 519 };
520 520
521 static void bd2802_led_work(struct work_struct *work) 521 static void bd2802_led_work(struct work_struct *work)
522 { 522 {
523 struct bd2802_led *led = container_of(work, struct bd2802_led, work); 523 struct bd2802_led *led = container_of(work, struct bd2802_led, work);
524 524
525 if (led->state) 525 if (led->state)
526 bd2802_turn_on(led, led->led_id, led->color, led->state); 526 bd2802_turn_on(led, led->led_id, led->color, led->state);
527 else 527 else
528 bd2802_turn_off(led, led->led_id, led->color); 528 bd2802_turn_off(led, led->led_id, led->color);
529 } 529 }
530 530
531 #define BD2802_CONTROL_RGBS(name, id, clr) \ 531 #define BD2802_CONTROL_RGBS(name, id, clr) \
532 static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\ 532 static void bd2802_set_##name##_brightness(struct led_classdev *led_cdev,\
533 enum led_brightness value) \ 533 enum led_brightness value) \
534 { \ 534 { \
535 struct bd2802_led *led = \ 535 struct bd2802_led *led = \
536 container_of(led_cdev, struct bd2802_led, cdev_##name); \ 536 container_of(led_cdev, struct bd2802_led, cdev_##name); \
537 led->led_id = id; \ 537 led->led_id = id; \
538 led->color = clr; \ 538 led->color = clr; \
539 if (value == LED_OFF) \ 539 if (value == LED_OFF) \
540 led->state = BD2802_OFF; \ 540 led->state = BD2802_OFF; \
541 else \ 541 else \
542 led->state = BD2802_ON; \ 542 led->state = BD2802_ON; \
543 schedule_work(&led->work); \ 543 schedule_work(&led->work); \
544 } \ 544 } \
545 static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \ 545 static int bd2802_set_##name##_blink(struct led_classdev *led_cdev, \
546 unsigned long *delay_on, unsigned long *delay_off) \ 546 unsigned long *delay_on, unsigned long *delay_off) \
547 { \ 547 { \
548 struct bd2802_led *led = \ 548 struct bd2802_led *led = \
549 container_of(led_cdev, struct bd2802_led, cdev_##name); \ 549 container_of(led_cdev, struct bd2802_led, cdev_##name); \
550 if (*delay_on == 0 || *delay_off == 0) \ 550 if (*delay_on == 0 || *delay_off == 0) \
551 return -EINVAL; \ 551 return -EINVAL; \
552 led->led_id = id; \ 552 led->led_id = id; \
553 led->color = clr; \ 553 led->color = clr; \
554 led->state = BD2802_BLINK; \ 554 led->state = BD2802_BLINK; \
555 schedule_work(&led->work); \ 555 schedule_work(&led->work); \
556 return 0; \ 556 return 0; \
557 } 557 }
558 558
559 BD2802_CONTROL_RGBS(led1r, LED1, RED); 559 BD2802_CONTROL_RGBS(led1r, LED1, RED);
560 BD2802_CONTROL_RGBS(led1g, LED1, GREEN); 560 BD2802_CONTROL_RGBS(led1g, LED1, GREEN);
561 BD2802_CONTROL_RGBS(led1b, LED1, BLUE); 561 BD2802_CONTROL_RGBS(led1b, LED1, BLUE);
562 BD2802_CONTROL_RGBS(led2r, LED2, RED); 562 BD2802_CONTROL_RGBS(led2r, LED2, RED);
563 BD2802_CONTROL_RGBS(led2g, LED2, GREEN); 563 BD2802_CONTROL_RGBS(led2g, LED2, GREEN);
564 BD2802_CONTROL_RGBS(led2b, LED2, BLUE); 564 BD2802_CONTROL_RGBS(led2b, LED2, BLUE);
565 565
566 static int bd2802_register_led_classdev(struct bd2802_led *led) 566 static int bd2802_register_led_classdev(struct bd2802_led *led)
567 { 567 {
568 int ret; 568 int ret;
569 569
570 INIT_WORK(&led->work, bd2802_led_work); 570 INIT_WORK(&led->work, bd2802_led_work);
571 571
572 led->cdev_led1r.name = "led1_R"; 572 led->cdev_led1r.name = "led1_R";
573 led->cdev_led1r.brightness = LED_OFF; 573 led->cdev_led1r.brightness = LED_OFF;
574 led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness; 574 led->cdev_led1r.brightness_set = bd2802_set_led1r_brightness;
575 led->cdev_led1r.blink_set = bd2802_set_led1r_blink; 575 led->cdev_led1r.blink_set = bd2802_set_led1r_blink;
576 576
577 ret = led_classdev_register(&led->client->dev, &led->cdev_led1r); 577 ret = led_classdev_register(&led->client->dev, &led->cdev_led1r);
578 if (ret < 0) { 578 if (ret < 0) {
579 dev_err(&led->client->dev, "couldn't register LED %s\n", 579 dev_err(&led->client->dev, "couldn't register LED %s\n",
580 led->cdev_led1r.name); 580 led->cdev_led1r.name);
581 goto failed_unregister_led1_R; 581 goto failed_unregister_led1_R;
582 } 582 }
583 583
584 led->cdev_led1g.name = "led1_G"; 584 led->cdev_led1g.name = "led1_G";
585 led->cdev_led1g.brightness = LED_OFF; 585 led->cdev_led1g.brightness = LED_OFF;
586 led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness; 586 led->cdev_led1g.brightness_set = bd2802_set_led1g_brightness;
587 led->cdev_led1g.blink_set = bd2802_set_led1g_blink; 587 led->cdev_led1g.blink_set = bd2802_set_led1g_blink;
588 588
589 ret = led_classdev_register(&led->client->dev, &led->cdev_led1g); 589 ret = led_classdev_register(&led->client->dev, &led->cdev_led1g);
590 if (ret < 0) { 590 if (ret < 0) {
591 dev_err(&led->client->dev, "couldn't register LED %s\n", 591 dev_err(&led->client->dev, "couldn't register LED %s\n",
592 led->cdev_led1g.name); 592 led->cdev_led1g.name);
593 goto failed_unregister_led1_G; 593 goto failed_unregister_led1_G;
594 } 594 }
595 595
596 led->cdev_led1b.name = "led1_B"; 596 led->cdev_led1b.name = "led1_B";
597 led->cdev_led1b.brightness = LED_OFF; 597 led->cdev_led1b.brightness = LED_OFF;
598 led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness; 598 led->cdev_led1b.brightness_set = bd2802_set_led1b_brightness;
599 led->cdev_led1b.blink_set = bd2802_set_led1b_blink; 599 led->cdev_led1b.blink_set = bd2802_set_led1b_blink;
600 600
601 ret = led_classdev_register(&led->client->dev, &led->cdev_led1b); 601 ret = led_classdev_register(&led->client->dev, &led->cdev_led1b);
602 if (ret < 0) { 602 if (ret < 0) {
603 dev_err(&led->client->dev, "couldn't register LED %s\n", 603 dev_err(&led->client->dev, "couldn't register LED %s\n",
604 led->cdev_led1b.name); 604 led->cdev_led1b.name);
605 goto failed_unregister_led1_B; 605 goto failed_unregister_led1_B;
606 } 606 }
607 607
608 led->cdev_led2r.name = "led2_R"; 608 led->cdev_led2r.name = "led2_R";
609 led->cdev_led2r.brightness = LED_OFF; 609 led->cdev_led2r.brightness = LED_OFF;
610 led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness; 610 led->cdev_led2r.brightness_set = bd2802_set_led2r_brightness;
611 led->cdev_led2r.blink_set = bd2802_set_led2r_blink; 611 led->cdev_led2r.blink_set = bd2802_set_led2r_blink;
612 612
613 ret = led_classdev_register(&led->client->dev, &led->cdev_led2r); 613 ret = led_classdev_register(&led->client->dev, &led->cdev_led2r);
614 if (ret < 0) { 614 if (ret < 0) {
615 dev_err(&led->client->dev, "couldn't register LED %s\n", 615 dev_err(&led->client->dev, "couldn't register LED %s\n",
616 led->cdev_led2r.name); 616 led->cdev_led2r.name);
617 goto failed_unregister_led2_R; 617 goto failed_unregister_led2_R;
618 } 618 }
619 619
620 led->cdev_led2g.name = "led2_G"; 620 led->cdev_led2g.name = "led2_G";
621 led->cdev_led2g.brightness = LED_OFF; 621 led->cdev_led2g.brightness = LED_OFF;
622 led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness; 622 led->cdev_led2g.brightness_set = bd2802_set_led2g_brightness;
623 led->cdev_led2g.blink_set = bd2802_set_led2g_blink; 623 led->cdev_led2g.blink_set = bd2802_set_led2g_blink;
624 624
625 ret = led_classdev_register(&led->client->dev, &led->cdev_led2g); 625 ret = led_classdev_register(&led->client->dev, &led->cdev_led2g);
626 if (ret < 0) { 626 if (ret < 0) {
627 dev_err(&led->client->dev, "couldn't register LED %s\n", 627 dev_err(&led->client->dev, "couldn't register LED %s\n",
628 led->cdev_led2g.name); 628 led->cdev_led2g.name);
629 goto failed_unregister_led2_G; 629 goto failed_unregister_led2_G;
630 } 630 }
631 631
632 led->cdev_led2b.name = "led2_B"; 632 led->cdev_led2b.name = "led2_B";
633 led->cdev_led2b.brightness = LED_OFF; 633 led->cdev_led2b.brightness = LED_OFF;
634 led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness; 634 led->cdev_led2b.brightness_set = bd2802_set_led2b_brightness;
635 led->cdev_led2b.blink_set = bd2802_set_led2b_blink; 635 led->cdev_led2b.blink_set = bd2802_set_led2b_blink;
636 led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME; 636 led->cdev_led2b.flags |= LED_CORE_SUSPENDRESUME;
637 637
638 ret = led_classdev_register(&led->client->dev, &led->cdev_led2b); 638 ret = led_classdev_register(&led->client->dev, &led->cdev_led2b);
639 if (ret < 0) { 639 if (ret < 0) {
640 dev_err(&led->client->dev, "couldn't register LED %s\n", 640 dev_err(&led->client->dev, "couldn't register LED %s\n",
641 led->cdev_led2b.name); 641 led->cdev_led2b.name);
642 goto failed_unregister_led2_B; 642 goto failed_unregister_led2_B;
643 } 643 }
644 644
645 return 0; 645 return 0;
646 646
647 failed_unregister_led2_B: 647 failed_unregister_led2_B:
648 led_classdev_unregister(&led->cdev_led2g); 648 led_classdev_unregister(&led->cdev_led2g);
649 failed_unregister_led2_G: 649 failed_unregister_led2_G:
650 led_classdev_unregister(&led->cdev_led2r); 650 led_classdev_unregister(&led->cdev_led2r);
651 failed_unregister_led2_R: 651 failed_unregister_led2_R:
652 led_classdev_unregister(&led->cdev_led1b); 652 led_classdev_unregister(&led->cdev_led1b);
653 failed_unregister_led1_B: 653 failed_unregister_led1_B:
654 led_classdev_unregister(&led->cdev_led1g); 654 led_classdev_unregister(&led->cdev_led1g);
655 failed_unregister_led1_G: 655 failed_unregister_led1_G:
656 led_classdev_unregister(&led->cdev_led1r); 656 led_classdev_unregister(&led->cdev_led1r);
657 failed_unregister_led1_R: 657 failed_unregister_led1_R:
658 658
659 return ret; 659 return ret;
660 } 660 }
661 661
662 static void bd2802_unregister_led_classdev(struct bd2802_led *led) 662 static void bd2802_unregister_led_classdev(struct bd2802_led *led)
663 { 663 {
664 cancel_work_sync(&led->work); 664 cancel_work_sync(&led->work);
665 led_classdev_unregister(&led->cdev_led2b); 665 led_classdev_unregister(&led->cdev_led2b);
666 led_classdev_unregister(&led->cdev_led2g); 666 led_classdev_unregister(&led->cdev_led2g);
667 led_classdev_unregister(&led->cdev_led2r); 667 led_classdev_unregister(&led->cdev_led2r);
668 led_classdev_unregister(&led->cdev_led1b); 668 led_classdev_unregister(&led->cdev_led1b);
669 led_classdev_unregister(&led->cdev_led1g); 669 led_classdev_unregister(&led->cdev_led1g);
670 led_classdev_unregister(&led->cdev_led1r); 670 led_classdev_unregister(&led->cdev_led1r);
671 } 671 }
672 672
673 static int bd2802_probe(struct i2c_client *client, 673 static int bd2802_probe(struct i2c_client *client,
674 const struct i2c_device_id *id) 674 const struct i2c_device_id *id)
675 { 675 {
676 struct bd2802_led *led; 676 struct bd2802_led *led;
677 struct bd2802_led_platform_data *pdata; 677 struct bd2802_led_platform_data *pdata;
678 int ret, i; 678 int ret, i;
679 679
680 led = devm_kzalloc(&client->dev, sizeof(struct bd2802_led), GFP_KERNEL); 680 led = devm_kzalloc(&client->dev, sizeof(struct bd2802_led), GFP_KERNEL);
681 if (!led) { 681 if (!led) {
682 dev_err(&client->dev, "failed to allocate driver data\n"); 682 dev_err(&client->dev, "failed to allocate driver data\n");
683 return -ENOMEM; 683 return -ENOMEM;
684 } 684 }
685 685
686 led->client = client; 686 led->client = client;
687 pdata = led->pdata = client->dev.platform_data; 687 pdata = led->pdata = dev_get_platdata(&client->dev);
688 i2c_set_clientdata(client, led); 688 i2c_set_clientdata(client, led);
689 689
690 /* Configure RESET GPIO (L: RESET, H: RESET cancel) */ 690 /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
691 gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "RGB_RESETB"); 691 gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "RGB_RESETB");
692 692
693 /* Tacss = min 0.1ms */ 693 /* Tacss = min 0.1ms */
694 udelay(100); 694 udelay(100);
695 695
696 /* Detect BD2802GU */ 696 /* Detect BD2802GU */
697 ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00); 697 ret = bd2802_write_byte(client, BD2802_REG_CLKSETUP, 0x00);
698 if (ret < 0) { 698 if (ret < 0) {
699 dev_err(&client->dev, "failed to detect device\n"); 699 dev_err(&client->dev, "failed to detect device\n");
700 return ret; 700 return ret;
701 } else 701 } else
702 dev_info(&client->dev, "return 0x%02x\n", ret); 702 dev_info(&client->dev, "return 0x%02x\n", ret);
703 703
704 /* To save the power, reset BD2802 after detecting */ 704 /* To save the power, reset BD2802 after detecting */
705 gpio_set_value(led->pdata->reset_gpio, 0); 705 gpio_set_value(led->pdata->reset_gpio, 0);
706 706
707 /* Default attributes */ 707 /* Default attributes */
708 led->wave_pattern = BD2802_PATTERN_HALF; 708 led->wave_pattern = BD2802_PATTERN_HALF;
709 led->rgb_current = BD2802_CURRENT_032; 709 led->rgb_current = BD2802_CURRENT_032;
710 710
711 init_rwsem(&led->rwsem); 711 init_rwsem(&led->rwsem);
712 712
713 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) { 713 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) {
714 ret = device_create_file(&led->client->dev, 714 ret = device_create_file(&led->client->dev,
715 bd2802_attributes[i]); 715 bd2802_attributes[i]);
716 if (ret) { 716 if (ret) {
717 dev_err(&led->client->dev, "failed: sysfs file %s\n", 717 dev_err(&led->client->dev, "failed: sysfs file %s\n",
718 bd2802_attributes[i]->attr.name); 718 bd2802_attributes[i]->attr.name);
719 goto failed_unregister_dev_file; 719 goto failed_unregister_dev_file;
720 } 720 }
721 } 721 }
722 722
723 ret = bd2802_register_led_classdev(led); 723 ret = bd2802_register_led_classdev(led);
724 if (ret < 0) 724 if (ret < 0)
725 goto failed_unregister_dev_file; 725 goto failed_unregister_dev_file;
726 726
727 return 0; 727 return 0;
728 728
729 failed_unregister_dev_file: 729 failed_unregister_dev_file:
730 for (i--; i >= 0; i--) 730 for (i--; i >= 0; i--)
731 device_remove_file(&led->client->dev, bd2802_attributes[i]); 731 device_remove_file(&led->client->dev, bd2802_attributes[i]);
732 return ret; 732 return ret;
733 } 733 }
734 734
735 static int bd2802_remove(struct i2c_client *client) 735 static int bd2802_remove(struct i2c_client *client)
736 { 736 {
737 struct bd2802_led *led = i2c_get_clientdata(client); 737 struct bd2802_led *led = i2c_get_clientdata(client);
738 int i; 738 int i;
739 739
740 gpio_set_value(led->pdata->reset_gpio, 0); 740 gpio_set_value(led->pdata->reset_gpio, 0);
741 bd2802_unregister_led_classdev(led); 741 bd2802_unregister_led_classdev(led);
742 if (led->adf_on) 742 if (led->adf_on)
743 bd2802_disable_adv_conf(led); 743 bd2802_disable_adv_conf(led);
744 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++) 744 for (i = 0; i < ARRAY_SIZE(bd2802_attributes); i++)
745 device_remove_file(&led->client->dev, bd2802_attributes[i]); 745 device_remove_file(&led->client->dev, bd2802_attributes[i]);
746 746
747 return 0; 747 return 0;
748 } 748 }
749 749
750 #ifdef CONFIG_PM_SLEEP 750 #ifdef CONFIG_PM_SLEEP
751 static void bd2802_restore_state(struct bd2802_led *led) 751 static void bd2802_restore_state(struct bd2802_led *led)
752 { 752 {
753 int i; 753 int i;
754 754
755 for (i = 0; i < LED_NUM; i++) { 755 for (i = 0; i < LED_NUM; i++) {
756 if (led->led[i].r) 756 if (led->led[i].r)
757 bd2802_turn_on(led, i, RED, led->led[i].r); 757 bd2802_turn_on(led, i, RED, led->led[i].r);
758 if (led->led[i].g) 758 if (led->led[i].g)
759 bd2802_turn_on(led, i, GREEN, led->led[i].g); 759 bd2802_turn_on(led, i, GREEN, led->led[i].g);
760 if (led->led[i].b) 760 if (led->led[i].b)
761 bd2802_turn_on(led, i, BLUE, led->led[i].b); 761 bd2802_turn_on(led, i, BLUE, led->led[i].b);
762 } 762 }
763 } 763 }
764 764
765 static int bd2802_suspend(struct device *dev) 765 static int bd2802_suspend(struct device *dev)
766 { 766 {
767 struct i2c_client *client = to_i2c_client(dev); 767 struct i2c_client *client = to_i2c_client(dev);
768 struct bd2802_led *led = i2c_get_clientdata(client); 768 struct bd2802_led *led = i2c_get_clientdata(client);
769 769
770 gpio_set_value(led->pdata->reset_gpio, 0); 770 gpio_set_value(led->pdata->reset_gpio, 0);
771 771
772 return 0; 772 return 0;
773 } 773 }
774 774
775 static int bd2802_resume(struct device *dev) 775 static int bd2802_resume(struct device *dev)
776 { 776 {
777 struct i2c_client *client = to_i2c_client(dev); 777 struct i2c_client *client = to_i2c_client(dev);
778 struct bd2802_led *led = i2c_get_clientdata(client); 778 struct bd2802_led *led = i2c_get_clientdata(client);
779 779
780 if (!bd2802_is_all_off(led) || led->adf_on) { 780 if (!bd2802_is_all_off(led) || led->adf_on) {
781 bd2802_reset_cancel(led); 781 bd2802_reset_cancel(led);
782 bd2802_restore_state(led); 782 bd2802_restore_state(led);
783 } 783 }
784 784
785 return 0; 785 return 0;
786 } 786 }
787 #endif 787 #endif
788 788
789 static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume); 789 static SIMPLE_DEV_PM_OPS(bd2802_pm, bd2802_suspend, bd2802_resume);
790 790
791 static const struct i2c_device_id bd2802_id[] = { 791 static const struct i2c_device_id bd2802_id[] = {
792 { "BD2802", 0 }, 792 { "BD2802", 0 },
793 { } 793 { }
794 }; 794 };
795 MODULE_DEVICE_TABLE(i2c, bd2802_id); 795 MODULE_DEVICE_TABLE(i2c, bd2802_id);
796 796
797 static struct i2c_driver bd2802_i2c_driver = { 797 static struct i2c_driver bd2802_i2c_driver = {
798 .driver = { 798 .driver = {
799 .name = "BD2802", 799 .name = "BD2802",
800 .pm = &bd2802_pm, 800 .pm = &bd2802_pm,
801 }, 801 },
802 .probe = bd2802_probe, 802 .probe = bd2802_probe,
803 .remove = bd2802_remove, 803 .remove = bd2802_remove,
804 .id_table = bd2802_id, 804 .id_table = bd2802_id,
805 }; 805 };
806 806
807 module_i2c_driver(bd2802_i2c_driver); 807 module_i2c_driver(bd2802_i2c_driver);
808 808
809 MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>"); 809 MODULE_AUTHOR("Kim Kyuwon <q1.kim@samsung.com>");
810 MODULE_DESCRIPTION("BD2802 LED driver"); 810 MODULE_DESCRIPTION("BD2802 LED driver");
811 MODULE_LICENSE("GPL v2"); 811 MODULE_LICENSE("GPL v2");
812 812
drivers/leds/leds-da903x.c
1 /* 1 /*
2 * LEDs driver for Dialog Semiconductor DA9030/DA9034 2 * LEDs driver for Dialog Semiconductor DA9030/DA9034
3 * 3 *
4 * Copyright (C) 2008 Compulab, Ltd. 4 * Copyright (C) 2008 Compulab, Ltd.
5 * Mike Rapoport <mike@compulab.co.il> 5 * Mike Rapoport <mike@compulab.co.il>
6 * 6 *
7 * Copyright (C) 2006-2008 Marvell International Ltd. 7 * Copyright (C) 2006-2008 Marvell International Ltd.
8 * Eric Miao <eric.miao@marvell.com> 8 * Eric Miao <eric.miao@marvell.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/kernel.h> 16 #include <linux/kernel.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/platform_device.h> 18 #include <linux/platform_device.h>
19 #include <linux/leds.h> 19 #include <linux/leds.h>
20 #include <linux/workqueue.h> 20 #include <linux/workqueue.h>
21 #include <linux/mfd/da903x.h> 21 #include <linux/mfd/da903x.h>
22 #include <linux/slab.h> 22 #include <linux/slab.h>
23 23
24 #define DA9030_LED1_CONTROL 0x20 24 #define DA9030_LED1_CONTROL 0x20
25 #define DA9030_LED2_CONTROL 0x21 25 #define DA9030_LED2_CONTROL 0x21
26 #define DA9030_LED3_CONTROL 0x22 26 #define DA9030_LED3_CONTROL 0x22
27 #define DA9030_LED4_CONTROL 0x23 27 #define DA9030_LED4_CONTROL 0x23
28 #define DA9030_LEDPC_CONTROL 0x24 28 #define DA9030_LEDPC_CONTROL 0x24
29 #define DA9030_MISC_CONTROL_A 0x26 /* Vibrator Control */ 29 #define DA9030_MISC_CONTROL_A 0x26 /* Vibrator Control */
30 30
31 #define DA9034_LED1_CONTROL 0x35 31 #define DA9034_LED1_CONTROL 0x35
32 #define DA9034_LED2_CONTROL 0x36 32 #define DA9034_LED2_CONTROL 0x36
33 #define DA9034_VIBRA 0x40 33 #define DA9034_VIBRA 0x40
34 34
35 struct da903x_led { 35 struct da903x_led {
36 struct led_classdev cdev; 36 struct led_classdev cdev;
37 struct work_struct work; 37 struct work_struct work;
38 struct device *master; 38 struct device *master;
39 enum led_brightness new_brightness; 39 enum led_brightness new_brightness;
40 int id; 40 int id;
41 int flags; 41 int flags;
42 }; 42 };
43 43
44 #define DA9030_LED_OFFSET(id) ((id) - DA9030_ID_LED_1) 44 #define DA9030_LED_OFFSET(id) ((id) - DA9030_ID_LED_1)
45 #define DA9034_LED_OFFSET(id) ((id) - DA9034_ID_LED_1) 45 #define DA9034_LED_OFFSET(id) ((id) - DA9034_ID_LED_1)
46 46
47 static void da903x_led_work(struct work_struct *work) 47 static void da903x_led_work(struct work_struct *work)
48 { 48 {
49 struct da903x_led *led = container_of(work, struct da903x_led, work); 49 struct da903x_led *led = container_of(work, struct da903x_led, work);
50 uint8_t val; 50 uint8_t val;
51 int offset; 51 int offset;
52 52
53 switch (led->id) { 53 switch (led->id) {
54 case DA9030_ID_LED_1: 54 case DA9030_ID_LED_1:
55 case DA9030_ID_LED_2: 55 case DA9030_ID_LED_2:
56 case DA9030_ID_LED_3: 56 case DA9030_ID_LED_3:
57 case DA9030_ID_LED_4: 57 case DA9030_ID_LED_4:
58 case DA9030_ID_LED_PC: 58 case DA9030_ID_LED_PC:
59 offset = DA9030_LED_OFFSET(led->id); 59 offset = DA9030_LED_OFFSET(led->id);
60 val = led->flags & ~0x87; 60 val = led->flags & ~0x87;
61 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */ 61 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
62 val |= (0x7 - (led->new_brightness >> 5)) & 0x7; /* PWM<2:0> */ 62 val |= (0x7 - (led->new_brightness >> 5)) & 0x7; /* PWM<2:0> */
63 da903x_write(led->master, DA9030_LED1_CONTROL + offset, val); 63 da903x_write(led->master, DA9030_LED1_CONTROL + offset, val);
64 break; 64 break;
65 case DA9030_ID_VIBRA: 65 case DA9030_ID_VIBRA:
66 val = led->flags & ~0x80; 66 val = led->flags & ~0x80;
67 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */ 67 val |= (led->new_brightness) ? 0x80 : 0; /* EN bit */
68 da903x_write(led->master, DA9030_MISC_CONTROL_A, val); 68 da903x_write(led->master, DA9030_MISC_CONTROL_A, val);
69 break; 69 break;
70 case DA9034_ID_LED_1: 70 case DA9034_ID_LED_1:
71 case DA9034_ID_LED_2: 71 case DA9034_ID_LED_2:
72 offset = DA9034_LED_OFFSET(led->id); 72 offset = DA9034_LED_OFFSET(led->id);
73 val = (led->new_brightness * 0x5f / LED_FULL) & 0x7f; 73 val = (led->new_brightness * 0x5f / LED_FULL) & 0x7f;
74 val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0; 74 val |= (led->flags & DA9034_LED_RAMP) ? 0x80 : 0;
75 da903x_write(led->master, DA9034_LED1_CONTROL + offset, val); 75 da903x_write(led->master, DA9034_LED1_CONTROL + offset, val);
76 break; 76 break;
77 case DA9034_ID_VIBRA: 77 case DA9034_ID_VIBRA:
78 val = led->new_brightness & 0xfe; 78 val = led->new_brightness & 0xfe;
79 da903x_write(led->master, DA9034_VIBRA, val); 79 da903x_write(led->master, DA9034_VIBRA, val);
80 break; 80 break;
81 } 81 }
82 } 82 }
83 83
84 static void da903x_led_set(struct led_classdev *led_cdev, 84 static void da903x_led_set(struct led_classdev *led_cdev,
85 enum led_brightness value) 85 enum led_brightness value)
86 { 86 {
87 struct da903x_led *led; 87 struct da903x_led *led;
88 88
89 led = container_of(led_cdev, struct da903x_led, cdev); 89 led = container_of(led_cdev, struct da903x_led, cdev);
90 led->new_brightness = value; 90 led->new_brightness = value;
91 schedule_work(&led->work); 91 schedule_work(&led->work);
92 } 92 }
93 93
94 static int da903x_led_probe(struct platform_device *pdev) 94 static int da903x_led_probe(struct platform_device *pdev)
95 { 95 {
96 struct led_info *pdata = pdev->dev.platform_data; 96 struct led_info *pdata = dev_get_platdata(&pdev->dev);
97 struct da903x_led *led; 97 struct da903x_led *led;
98 int id, ret; 98 int id, ret;
99 99
100 if (pdata == NULL) 100 if (pdata == NULL)
101 return 0; 101 return 0;
102 102
103 id = pdev->id; 103 id = pdev->id;
104 104
105 if (!((id >= DA9030_ID_LED_1 && id <= DA9030_ID_VIBRA) || 105 if (!((id >= DA9030_ID_LED_1 && id <= DA9030_ID_VIBRA) ||
106 (id >= DA9034_ID_LED_1 && id <= DA9034_ID_VIBRA))) { 106 (id >= DA9034_ID_LED_1 && id <= DA9034_ID_VIBRA))) {
107 dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", id); 107 dev_err(&pdev->dev, "invalid LED ID (%d) specified\n", id);
108 return -EINVAL; 108 return -EINVAL;
109 } 109 }
110 110
111 led = devm_kzalloc(&pdev->dev, sizeof(struct da903x_led), GFP_KERNEL); 111 led = devm_kzalloc(&pdev->dev, sizeof(struct da903x_led), GFP_KERNEL);
112 if (led == NULL) { 112 if (led == NULL) {
113 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id); 113 dev_err(&pdev->dev, "failed to alloc memory for LED%d\n", id);
114 return -ENOMEM; 114 return -ENOMEM;
115 } 115 }
116 116
117 led->cdev.name = pdata->name; 117 led->cdev.name = pdata->name;
118 led->cdev.default_trigger = pdata->default_trigger; 118 led->cdev.default_trigger = pdata->default_trigger;
119 led->cdev.brightness_set = da903x_led_set; 119 led->cdev.brightness_set = da903x_led_set;
120 led->cdev.brightness = LED_OFF; 120 led->cdev.brightness = LED_OFF;
121 121
122 led->id = id; 122 led->id = id;
123 led->flags = pdata->flags; 123 led->flags = pdata->flags;
124 led->master = pdev->dev.parent; 124 led->master = pdev->dev.parent;
125 led->new_brightness = LED_OFF; 125 led->new_brightness = LED_OFF;
126 126
127 INIT_WORK(&led->work, da903x_led_work); 127 INIT_WORK(&led->work, da903x_led_work);
128 128
129 ret = led_classdev_register(led->master, &led->cdev); 129 ret = led_classdev_register(led->master, &led->cdev);
130 if (ret) { 130 if (ret) {
131 dev_err(&pdev->dev, "failed to register LED %d\n", id); 131 dev_err(&pdev->dev, "failed to register LED %d\n", id);
132 return ret; 132 return ret;
133 } 133 }
134 134
135 platform_set_drvdata(pdev, led); 135 platform_set_drvdata(pdev, led);
136 return 0; 136 return 0;
137 } 137 }
138 138
139 static int da903x_led_remove(struct platform_device *pdev) 139 static int da903x_led_remove(struct platform_device *pdev)
140 { 140 {
141 struct da903x_led *led = platform_get_drvdata(pdev); 141 struct da903x_led *led = platform_get_drvdata(pdev);
142 142
143 led_classdev_unregister(&led->cdev); 143 led_classdev_unregister(&led->cdev);
144 return 0; 144 return 0;
145 } 145 }
146 146
147 static struct platform_driver da903x_led_driver = { 147 static struct platform_driver da903x_led_driver = {
148 .driver = { 148 .driver = {
149 .name = "da903x-led", 149 .name = "da903x-led",
150 .owner = THIS_MODULE, 150 .owner = THIS_MODULE,
151 }, 151 },
152 .probe = da903x_led_probe, 152 .probe = da903x_led_probe,
153 .remove = da903x_led_remove, 153 .remove = da903x_led_remove,
154 }; 154 };
155 155
156 module_platform_driver(da903x_led_driver); 156 module_platform_driver(da903x_led_driver);
157 157
158 MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034"); 158 MODULE_DESCRIPTION("LEDs driver for Dialog Semiconductor DA9030/DA9034");
159 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>"); 159 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
160 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); 160 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
161 MODULE_LICENSE("GPL"); 161 MODULE_LICENSE("GPL");
162 MODULE_ALIAS("platform:da903x-led"); 162 MODULE_ALIAS("platform:da903x-led");
163 163
drivers/leds/leds-da9052.c
1 /* 1 /*
2 * LED Driver for Dialog DA9052 PMICs. 2 * LED Driver for Dialog DA9052 PMICs.
3 * 3 *
4 * Copyright(c) 2012 Dialog Semiconductor Ltd. 4 * Copyright(c) 2012 Dialog Semiconductor Ltd.
5 * 5 *
6 * Author: David Dajun Chen <dchen@diasemi.com> 6 * Author: David Dajun Chen <dchen@diasemi.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 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 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 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 * 12 *
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/kernel.h> 16 #include <linux/kernel.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/platform_device.h> 18 #include <linux/platform_device.h>
19 #include <linux/leds.h> 19 #include <linux/leds.h>
20 #include <linux/workqueue.h> 20 #include <linux/workqueue.h>
21 #include <linux/slab.h> 21 #include <linux/slab.h>
22 22
23 #include <linux/mfd/da9052/reg.h> 23 #include <linux/mfd/da9052/reg.h>
24 #include <linux/mfd/da9052/da9052.h> 24 #include <linux/mfd/da9052/da9052.h>
25 #include <linux/mfd/da9052/pdata.h> 25 #include <linux/mfd/da9052/pdata.h>
26 26
27 #define DA9052_OPENDRAIN_OUTPUT 2 27 #define DA9052_OPENDRAIN_OUTPUT 2
28 #define DA9052_SET_HIGH_LVL_OUTPUT (1 << 3) 28 #define DA9052_SET_HIGH_LVL_OUTPUT (1 << 3)
29 #define DA9052_MASK_UPPER_NIBBLE 0xF0 29 #define DA9052_MASK_UPPER_NIBBLE 0xF0
30 #define DA9052_MASK_LOWER_NIBBLE 0x0F 30 #define DA9052_MASK_LOWER_NIBBLE 0x0F
31 #define DA9052_NIBBLE_SHIFT 4 31 #define DA9052_NIBBLE_SHIFT 4
32 #define DA9052_MAX_BRIGHTNESS 0x5f 32 #define DA9052_MAX_BRIGHTNESS 0x5f
33 33
34 struct da9052_led { 34 struct da9052_led {
35 struct led_classdev cdev; 35 struct led_classdev cdev;
36 struct work_struct work; 36 struct work_struct work;
37 struct da9052 *da9052; 37 struct da9052 *da9052;
38 unsigned char led_index; 38 unsigned char led_index;
39 unsigned char id; 39 unsigned char id;
40 int brightness; 40 int brightness;
41 }; 41 };
42 42
43 static unsigned char led_reg[] = { 43 static unsigned char led_reg[] = {
44 DA9052_LED_CONT_4_REG, 44 DA9052_LED_CONT_4_REG,
45 DA9052_LED_CONT_5_REG, 45 DA9052_LED_CONT_5_REG,
46 }; 46 };
47 47
48 static int da9052_set_led_brightness(struct da9052_led *led) 48 static int da9052_set_led_brightness(struct da9052_led *led)
49 { 49 {
50 u8 val; 50 u8 val;
51 int error; 51 int error;
52 52
53 val = (led->brightness & 0x7f) | DA9052_LED_CONT_DIM; 53 val = (led->brightness & 0x7f) | DA9052_LED_CONT_DIM;
54 54
55 error = da9052_reg_write(led->da9052, led_reg[led->led_index], val); 55 error = da9052_reg_write(led->da9052, led_reg[led->led_index], val);
56 if (error < 0) 56 if (error < 0)
57 dev_err(led->da9052->dev, "Failed to set led brightness, %d\n", 57 dev_err(led->da9052->dev, "Failed to set led brightness, %d\n",
58 error); 58 error);
59 return error; 59 return error;
60 } 60 }
61 61
62 static void da9052_led_work(struct work_struct *work) 62 static void da9052_led_work(struct work_struct *work)
63 { 63 {
64 struct da9052_led *led = container_of(work, struct da9052_led, work); 64 struct da9052_led *led = container_of(work, struct da9052_led, work);
65 65
66 da9052_set_led_brightness(led); 66 da9052_set_led_brightness(led);
67 } 67 }
68 68
69 static void da9052_led_set(struct led_classdev *led_cdev, 69 static void da9052_led_set(struct led_classdev *led_cdev,
70 enum led_brightness value) 70 enum led_brightness value)
71 { 71 {
72 struct da9052_led *led; 72 struct da9052_led *led;
73 73
74 led = container_of(led_cdev, struct da9052_led, cdev); 74 led = container_of(led_cdev, struct da9052_led, cdev);
75 led->brightness = value; 75 led->brightness = value;
76 schedule_work(&led->work); 76 schedule_work(&led->work);
77 } 77 }
78 78
79 static int da9052_configure_leds(struct da9052 *da9052) 79 static int da9052_configure_leds(struct da9052 *da9052)
80 { 80 {
81 int error; 81 int error;
82 unsigned char register_value = DA9052_OPENDRAIN_OUTPUT 82 unsigned char register_value = DA9052_OPENDRAIN_OUTPUT
83 | DA9052_SET_HIGH_LVL_OUTPUT; 83 | DA9052_SET_HIGH_LVL_OUTPUT;
84 84
85 error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG, 85 error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG,
86 DA9052_MASK_LOWER_NIBBLE, 86 DA9052_MASK_LOWER_NIBBLE,
87 register_value); 87 register_value);
88 88
89 if (error < 0) { 89 if (error < 0) {
90 dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n", 90 dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n",
91 error); 91 error);
92 return error; 92 return error;
93 } 93 }
94 94
95 error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG, 95 error = da9052_reg_update(da9052, DA9052_GPIO_14_15_REG,
96 DA9052_MASK_UPPER_NIBBLE, 96 DA9052_MASK_UPPER_NIBBLE,
97 register_value << DA9052_NIBBLE_SHIFT); 97 register_value << DA9052_NIBBLE_SHIFT);
98 if (error < 0) 98 if (error < 0)
99 dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n", 99 dev_err(da9052->dev, "Failed to write GPIO 14-15 reg, %d\n",
100 error); 100 error);
101 101
102 return error; 102 return error;
103 } 103 }
104 104
105 static int da9052_led_probe(struct platform_device *pdev) 105 static int da9052_led_probe(struct platform_device *pdev)
106 { 106 {
107 struct da9052_pdata *pdata; 107 struct da9052_pdata *pdata;
108 struct da9052 *da9052; 108 struct da9052 *da9052;
109 struct led_platform_data *pled; 109 struct led_platform_data *pled;
110 struct da9052_led *led = NULL; 110 struct da9052_led *led = NULL;
111 int error = -ENODEV; 111 int error = -ENODEV;
112 int i; 112 int i;
113 113
114 da9052 = dev_get_drvdata(pdev->dev.parent); 114 da9052 = dev_get_drvdata(pdev->dev.parent);
115 pdata = da9052->dev->platform_data; 115 pdata = dev_get_platdata(da9052->dev);
116 if (pdata == NULL) { 116 if (pdata == NULL) {
117 dev_err(&pdev->dev, "No platform data\n"); 117 dev_err(&pdev->dev, "No platform data\n");
118 goto err; 118 goto err;
119 } 119 }
120 120
121 pled = pdata->pled; 121 pled = pdata->pled;
122 if (pled == NULL) { 122 if (pled == NULL) {
123 dev_err(&pdev->dev, "No platform data for LED\n"); 123 dev_err(&pdev->dev, "No platform data for LED\n");
124 goto err; 124 goto err;
125 } 125 }
126 126
127 led = devm_kzalloc(&pdev->dev, 127 led = devm_kzalloc(&pdev->dev,
128 sizeof(struct da9052_led) * pled->num_leds, 128 sizeof(struct da9052_led) * pled->num_leds,
129 GFP_KERNEL); 129 GFP_KERNEL);
130 if (led == NULL) { 130 if (led == NULL) {
131 dev_err(&pdev->dev, "Failed to alloc memory\n"); 131 dev_err(&pdev->dev, "Failed to alloc memory\n");
132 error = -ENOMEM; 132 error = -ENOMEM;
133 goto err; 133 goto err;
134 } 134 }
135 135
136 for (i = 0; i < pled->num_leds; i++) { 136 for (i = 0; i < pled->num_leds; i++) {
137 led[i].cdev.name = pled->leds[i].name; 137 led[i].cdev.name = pled->leds[i].name;
138 led[i].cdev.brightness_set = da9052_led_set; 138 led[i].cdev.brightness_set = da9052_led_set;
139 led[i].cdev.brightness = LED_OFF; 139 led[i].cdev.brightness = LED_OFF;
140 led[i].cdev.max_brightness = DA9052_MAX_BRIGHTNESS; 140 led[i].cdev.max_brightness = DA9052_MAX_BRIGHTNESS;
141 led[i].brightness = LED_OFF; 141 led[i].brightness = LED_OFF;
142 led[i].led_index = pled->leds[i].flags; 142 led[i].led_index = pled->leds[i].flags;
143 led[i].da9052 = dev_get_drvdata(pdev->dev.parent); 143 led[i].da9052 = dev_get_drvdata(pdev->dev.parent);
144 INIT_WORK(&led[i].work, da9052_led_work); 144 INIT_WORK(&led[i].work, da9052_led_work);
145 145
146 error = led_classdev_register(pdev->dev.parent, &led[i].cdev); 146 error = led_classdev_register(pdev->dev.parent, &led[i].cdev);
147 if (error) { 147 if (error) {
148 dev_err(&pdev->dev, "Failed to register led %d\n", 148 dev_err(&pdev->dev, "Failed to register led %d\n",
149 led[i].led_index); 149 led[i].led_index);
150 goto err_register; 150 goto err_register;
151 } 151 }
152 152
153 error = da9052_set_led_brightness(&led[i]); 153 error = da9052_set_led_brightness(&led[i]);
154 if (error) { 154 if (error) {
155 dev_err(&pdev->dev, "Unable to init led %d\n", 155 dev_err(&pdev->dev, "Unable to init led %d\n",
156 led[i].led_index); 156 led[i].led_index);
157 continue; 157 continue;
158 } 158 }
159 } 159 }
160 error = da9052_configure_leds(led->da9052); 160 error = da9052_configure_leds(led->da9052);
161 if (error) { 161 if (error) {
162 dev_err(&pdev->dev, "Failed to configure GPIO LED%d\n", error); 162 dev_err(&pdev->dev, "Failed to configure GPIO LED%d\n", error);
163 goto err_register; 163 goto err_register;
164 } 164 }
165 165
166 platform_set_drvdata(pdev, led); 166 platform_set_drvdata(pdev, led);
167 167
168 return 0; 168 return 0;
169 169
170 err_register: 170 err_register:
171 for (i = i - 1; i >= 0; i--) { 171 for (i = i - 1; i >= 0; i--) {
172 led_classdev_unregister(&led[i].cdev); 172 led_classdev_unregister(&led[i].cdev);
173 cancel_work_sync(&led[i].work); 173 cancel_work_sync(&led[i].work);
174 } 174 }
175 err: 175 err:
176 return error; 176 return error;
177 } 177 }
178 178
179 static int da9052_led_remove(struct platform_device *pdev) 179 static int da9052_led_remove(struct platform_device *pdev)
180 { 180 {
181 struct da9052_led *led = platform_get_drvdata(pdev); 181 struct da9052_led *led = platform_get_drvdata(pdev);
182 struct da9052_pdata *pdata; 182 struct da9052_pdata *pdata;
183 struct da9052 *da9052; 183 struct da9052 *da9052;
184 struct led_platform_data *pled; 184 struct led_platform_data *pled;
185 int i; 185 int i;
186 186
187 da9052 = dev_get_drvdata(pdev->dev.parent); 187 da9052 = dev_get_drvdata(pdev->dev.parent);
188 pdata = da9052->dev->platform_data; 188 pdata = dev_get_platdata(da9052->dev);
189 pled = pdata->pled; 189 pled = pdata->pled;
190 190
191 for (i = 0; i < pled->num_leds; i++) { 191 for (i = 0; i < pled->num_leds; i++) {
192 led[i].brightness = 0; 192 led[i].brightness = 0;
193 da9052_set_led_brightness(&led[i]); 193 da9052_set_led_brightness(&led[i]);
194 led_classdev_unregister(&led[i].cdev); 194 led_classdev_unregister(&led[i].cdev);
195 cancel_work_sync(&led[i].work); 195 cancel_work_sync(&led[i].work);
196 } 196 }
197 197
198 return 0; 198 return 0;
199 } 199 }
200 200
201 static struct platform_driver da9052_led_driver = { 201 static struct platform_driver da9052_led_driver = {
202 .driver = { 202 .driver = {
203 .name = "da9052-leds", 203 .name = "da9052-leds",
204 .owner = THIS_MODULE, 204 .owner = THIS_MODULE,
205 }, 205 },
206 .probe = da9052_led_probe, 206 .probe = da9052_led_probe,
207 .remove = da9052_led_remove, 207 .remove = da9052_led_remove,
208 }; 208 };
209 209
210 module_platform_driver(da9052_led_driver); 210 module_platform_driver(da9052_led_driver);
211 211
212 MODULE_AUTHOR("Dialog Semiconductor Ltd <dchen@diasemi.com>"); 212 MODULE_AUTHOR("Dialog Semiconductor Ltd <dchen@diasemi.com>");
213 MODULE_DESCRIPTION("LED driver for Dialog DA9052 PMIC"); 213 MODULE_DESCRIPTION("LED driver for Dialog DA9052 PMIC");
214 MODULE_LICENSE("GPL"); 214 MODULE_LICENSE("GPL");
215 215
drivers/leds/leds-gpio.c
1 /* 1 /*
2 * LEDs driver for GPIOs 2 * LEDs driver for GPIOs
3 * 3 *
4 * Copyright (C) 2007 8D Technologies inc. 4 * Copyright (C) 2007 8D Technologies inc.
5 * Raphael Assenat <raph@8d.com> 5 * Raphael Assenat <raph@8d.com>
6 * Copyright (C) 2008 Freescale Semiconductor, Inc. 6 * Copyright (C) 2008 Freescale Semiconductor, Inc.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 * 11 *
12 */ 12 */
13 #include <linux/kernel.h> 13 #include <linux/kernel.h>
14 #include <linux/init.h> 14 #include <linux/init.h>
15 #include <linux/platform_device.h> 15 #include <linux/platform_device.h>
16 #include <linux/gpio.h> 16 #include <linux/gpio.h>
17 #include <linux/leds.h> 17 #include <linux/leds.h>
18 #include <linux/of_platform.h> 18 #include <linux/of_platform.h>
19 #include <linux/of_gpio.h> 19 #include <linux/of_gpio.h>
20 #include <linux/slab.h> 20 #include <linux/slab.h>
21 #include <linux/workqueue.h> 21 #include <linux/workqueue.h>
22 #include <linux/module.h> 22 #include <linux/module.h>
23 #include <linux/err.h> 23 #include <linux/err.h>
24 24
25 struct gpio_led_data { 25 struct gpio_led_data {
26 struct led_classdev cdev; 26 struct led_classdev cdev;
27 unsigned gpio; 27 unsigned gpio;
28 struct work_struct work; 28 struct work_struct work;
29 u8 new_level; 29 u8 new_level;
30 u8 can_sleep; 30 u8 can_sleep;
31 u8 active_low; 31 u8 active_low;
32 u8 blinking; 32 u8 blinking;
33 int (*platform_gpio_blink_set)(unsigned gpio, int state, 33 int (*platform_gpio_blink_set)(unsigned gpio, int state,
34 unsigned long *delay_on, unsigned long *delay_off); 34 unsigned long *delay_on, unsigned long *delay_off);
35 }; 35 };
36 36
37 static void gpio_led_work(struct work_struct *work) 37 static void gpio_led_work(struct work_struct *work)
38 { 38 {
39 struct gpio_led_data *led_dat = 39 struct gpio_led_data *led_dat =
40 container_of(work, struct gpio_led_data, work); 40 container_of(work, struct gpio_led_data, work);
41 41
42 if (led_dat->blinking) { 42 if (led_dat->blinking) {
43 led_dat->platform_gpio_blink_set(led_dat->gpio, 43 led_dat->platform_gpio_blink_set(led_dat->gpio,
44 led_dat->new_level, 44 led_dat->new_level,
45 NULL, NULL); 45 NULL, NULL);
46 led_dat->blinking = 0; 46 led_dat->blinking = 0;
47 } else 47 } else
48 gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level); 48 gpio_set_value_cansleep(led_dat->gpio, led_dat->new_level);
49 } 49 }
50 50
51 static void gpio_led_set(struct led_classdev *led_cdev, 51 static void gpio_led_set(struct led_classdev *led_cdev,
52 enum led_brightness value) 52 enum led_brightness value)
53 { 53 {
54 struct gpio_led_data *led_dat = 54 struct gpio_led_data *led_dat =
55 container_of(led_cdev, struct gpio_led_data, cdev); 55 container_of(led_cdev, struct gpio_led_data, cdev);
56 int level; 56 int level;
57 57
58 if (value == LED_OFF) 58 if (value == LED_OFF)
59 level = 0; 59 level = 0;
60 else 60 else
61 level = 1; 61 level = 1;
62 62
63 if (led_dat->active_low) 63 if (led_dat->active_low)
64 level = !level; 64 level = !level;
65 65
66 /* Setting GPIOs with I2C/etc requires a task context, and we don't 66 /* Setting GPIOs with I2C/etc requires a task context, and we don't
67 * seem to have a reliable way to know if we're already in one; so 67 * seem to have a reliable way to know if we're already in one; so
68 * let's just assume the worst. 68 * let's just assume the worst.
69 */ 69 */
70 if (led_dat->can_sleep) { 70 if (led_dat->can_sleep) {
71 led_dat->new_level = level; 71 led_dat->new_level = level;
72 schedule_work(&led_dat->work); 72 schedule_work(&led_dat->work);
73 } else { 73 } else {
74 if (led_dat->blinking) { 74 if (led_dat->blinking) {
75 led_dat->platform_gpio_blink_set(led_dat->gpio, level, 75 led_dat->platform_gpio_blink_set(led_dat->gpio, level,
76 NULL, NULL); 76 NULL, NULL);
77 led_dat->blinking = 0; 77 led_dat->blinking = 0;
78 } else 78 } else
79 gpio_set_value(led_dat->gpio, level); 79 gpio_set_value(led_dat->gpio, level);
80 } 80 }
81 } 81 }
82 82
83 static int gpio_blink_set(struct led_classdev *led_cdev, 83 static int gpio_blink_set(struct led_classdev *led_cdev,
84 unsigned long *delay_on, unsigned long *delay_off) 84 unsigned long *delay_on, unsigned long *delay_off)
85 { 85 {
86 struct gpio_led_data *led_dat = 86 struct gpio_led_data *led_dat =
87 container_of(led_cdev, struct gpio_led_data, cdev); 87 container_of(led_cdev, struct gpio_led_data, cdev);
88 88
89 led_dat->blinking = 1; 89 led_dat->blinking = 1;
90 return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK, 90 return led_dat->platform_gpio_blink_set(led_dat->gpio, GPIO_LED_BLINK,
91 delay_on, delay_off); 91 delay_on, delay_off);
92 } 92 }
93 93
94 static int create_gpio_led(const struct gpio_led *template, 94 static int create_gpio_led(const struct gpio_led *template,
95 struct gpio_led_data *led_dat, struct device *parent, 95 struct gpio_led_data *led_dat, struct device *parent,
96 int (*blink_set)(unsigned, int, unsigned long *, unsigned long *)) 96 int (*blink_set)(unsigned, int, unsigned long *, unsigned long *))
97 { 97 {
98 int ret, state; 98 int ret, state;
99 99
100 led_dat->gpio = -1; 100 led_dat->gpio = -1;
101 101
102 /* skip leds that aren't available */ 102 /* skip leds that aren't available */
103 if (!gpio_is_valid(template->gpio)) { 103 if (!gpio_is_valid(template->gpio)) {
104 dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n", 104 dev_info(parent, "Skipping unavailable LED gpio %d (%s)\n",
105 template->gpio, template->name); 105 template->gpio, template->name);
106 return 0; 106 return 0;
107 } 107 }
108 108
109 ret = devm_gpio_request(parent, template->gpio, template->name); 109 ret = devm_gpio_request(parent, template->gpio, template->name);
110 if (ret < 0) 110 if (ret < 0)
111 return ret; 111 return ret;
112 112
113 led_dat->cdev.name = template->name; 113 led_dat->cdev.name = template->name;
114 led_dat->cdev.default_trigger = template->default_trigger; 114 led_dat->cdev.default_trigger = template->default_trigger;
115 led_dat->gpio = template->gpio; 115 led_dat->gpio = template->gpio;
116 led_dat->can_sleep = gpio_cansleep(template->gpio); 116 led_dat->can_sleep = gpio_cansleep(template->gpio);
117 led_dat->active_low = template->active_low; 117 led_dat->active_low = template->active_low;
118 led_dat->blinking = 0; 118 led_dat->blinking = 0;
119 if (blink_set) { 119 if (blink_set) {
120 led_dat->platform_gpio_blink_set = blink_set; 120 led_dat->platform_gpio_blink_set = blink_set;
121 led_dat->cdev.blink_set = gpio_blink_set; 121 led_dat->cdev.blink_set = gpio_blink_set;
122 } 122 }
123 led_dat->cdev.brightness_set = gpio_led_set; 123 led_dat->cdev.brightness_set = gpio_led_set;
124 if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP) 124 if (template->default_state == LEDS_GPIO_DEFSTATE_KEEP)
125 state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low; 125 state = !!gpio_get_value_cansleep(led_dat->gpio) ^ led_dat->active_low;
126 else 126 else
127 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); 127 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
128 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; 128 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
129 if (!template->retain_state_suspended) 129 if (!template->retain_state_suspended)
130 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 130 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
131 131
132 ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state); 132 ret = gpio_direction_output(led_dat->gpio, led_dat->active_low ^ state);
133 if (ret < 0) 133 if (ret < 0)
134 return ret; 134 return ret;
135 135
136 INIT_WORK(&led_dat->work, gpio_led_work); 136 INIT_WORK(&led_dat->work, gpio_led_work);
137 137
138 ret = led_classdev_register(parent, &led_dat->cdev); 138 ret = led_classdev_register(parent, &led_dat->cdev);
139 if (ret < 0) 139 if (ret < 0)
140 return ret; 140 return ret;
141 141
142 return 0; 142 return 0;
143 } 143 }
144 144
145 static void delete_gpio_led(struct gpio_led_data *led) 145 static void delete_gpio_led(struct gpio_led_data *led)
146 { 146 {
147 if (!gpio_is_valid(led->gpio)) 147 if (!gpio_is_valid(led->gpio))
148 return; 148 return;
149 led_classdev_unregister(&led->cdev); 149 led_classdev_unregister(&led->cdev);
150 cancel_work_sync(&led->work); 150 cancel_work_sync(&led->work);
151 } 151 }
152 152
153 struct gpio_leds_priv { 153 struct gpio_leds_priv {
154 int num_leds; 154 int num_leds;
155 struct gpio_led_data leds[]; 155 struct gpio_led_data leds[];
156 }; 156 };
157 157
158 static inline int sizeof_gpio_leds_priv(int num_leds) 158 static inline int sizeof_gpio_leds_priv(int num_leds)
159 { 159 {
160 return sizeof(struct gpio_leds_priv) + 160 return sizeof(struct gpio_leds_priv) +
161 (sizeof(struct gpio_led_data) * num_leds); 161 (sizeof(struct gpio_led_data) * num_leds);
162 } 162 }
163 163
164 /* Code to create from OpenFirmware platform devices */ 164 /* Code to create from OpenFirmware platform devices */
165 #ifdef CONFIG_OF_GPIO 165 #ifdef CONFIG_OF_GPIO
166 static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) 166 static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
167 { 167 {
168 struct device_node *np = pdev->dev.of_node, *child; 168 struct device_node *np = pdev->dev.of_node, *child;
169 struct gpio_leds_priv *priv; 169 struct gpio_leds_priv *priv;
170 int count, ret; 170 int count, ret;
171 171
172 /* count LEDs in this device, so we know how much to allocate */ 172 /* count LEDs in this device, so we know how much to allocate */
173 count = of_get_child_count(np); 173 count = of_get_child_count(np);
174 if (!count) 174 if (!count)
175 return ERR_PTR(-ENODEV); 175 return ERR_PTR(-ENODEV);
176 176
177 for_each_child_of_node(np, child) 177 for_each_child_of_node(np, child)
178 if (of_get_gpio(child, 0) == -EPROBE_DEFER) 178 if (of_get_gpio(child, 0) == -EPROBE_DEFER)
179 return ERR_PTR(-EPROBE_DEFER); 179 return ERR_PTR(-EPROBE_DEFER);
180 180
181 priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count), 181 priv = devm_kzalloc(&pdev->dev, sizeof_gpio_leds_priv(count),
182 GFP_KERNEL); 182 GFP_KERNEL);
183 if (!priv) 183 if (!priv)
184 return ERR_PTR(-ENOMEM); 184 return ERR_PTR(-ENOMEM);
185 185
186 for_each_child_of_node(np, child) { 186 for_each_child_of_node(np, child) {
187 struct gpio_led led = {}; 187 struct gpio_led led = {};
188 enum of_gpio_flags flags; 188 enum of_gpio_flags flags;
189 const char *state; 189 const char *state;
190 190
191 led.gpio = of_get_gpio_flags(child, 0, &flags); 191 led.gpio = of_get_gpio_flags(child, 0, &flags);
192 led.active_low = flags & OF_GPIO_ACTIVE_LOW; 192 led.active_low = flags & OF_GPIO_ACTIVE_LOW;
193 led.name = of_get_property(child, "label", NULL) ? : child->name; 193 led.name = of_get_property(child, "label", NULL) ? : child->name;
194 led.default_trigger = 194 led.default_trigger =
195 of_get_property(child, "linux,default-trigger", NULL); 195 of_get_property(child, "linux,default-trigger", NULL);
196 state = of_get_property(child, "default-state", NULL); 196 state = of_get_property(child, "default-state", NULL);
197 if (state) { 197 if (state) {
198 if (!strcmp(state, "keep")) 198 if (!strcmp(state, "keep"))
199 led.default_state = LEDS_GPIO_DEFSTATE_KEEP; 199 led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
200 else if (!strcmp(state, "on")) 200 else if (!strcmp(state, "on"))
201 led.default_state = LEDS_GPIO_DEFSTATE_ON; 201 led.default_state = LEDS_GPIO_DEFSTATE_ON;
202 else 202 else
203 led.default_state = LEDS_GPIO_DEFSTATE_OFF; 203 led.default_state = LEDS_GPIO_DEFSTATE_OFF;
204 } 204 }
205 205
206 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++], 206 ret = create_gpio_led(&led, &priv->leds[priv->num_leds++],
207 &pdev->dev, NULL); 207 &pdev->dev, NULL);
208 if (ret < 0) { 208 if (ret < 0) {
209 of_node_put(child); 209 of_node_put(child);
210 goto err; 210 goto err;
211 } 211 }
212 } 212 }
213 213
214 return priv; 214 return priv;
215 215
216 err: 216 err:
217 for (count = priv->num_leds - 2; count >= 0; count--) 217 for (count = priv->num_leds - 2; count >= 0; count--)
218 delete_gpio_led(&priv->leds[count]); 218 delete_gpio_led(&priv->leds[count]);
219 return ERR_PTR(-ENODEV); 219 return ERR_PTR(-ENODEV);
220 } 220 }
221 221
222 static const struct of_device_id of_gpio_leds_match[] = { 222 static const struct of_device_id of_gpio_leds_match[] = {
223 { .compatible = "gpio-leds", }, 223 { .compatible = "gpio-leds", },
224 {}, 224 {},
225 }; 225 };
226 #else /* CONFIG_OF_GPIO */ 226 #else /* CONFIG_OF_GPIO */
227 static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev) 227 static struct gpio_leds_priv *gpio_leds_create_of(struct platform_device *pdev)
228 { 228 {
229 return ERR_PTR(-ENODEV); 229 return ERR_PTR(-ENODEV);
230 } 230 }
231 #endif /* CONFIG_OF_GPIO */ 231 #endif /* CONFIG_OF_GPIO */
232 232
233 233
234 static int gpio_led_probe(struct platform_device *pdev) 234 static int gpio_led_probe(struct platform_device *pdev)
235 { 235 {
236 struct gpio_led_platform_data *pdata = pdev->dev.platform_data; 236 struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
237 struct gpio_leds_priv *priv; 237 struct gpio_leds_priv *priv;
238 int i, ret = 0; 238 int i, ret = 0;
239 239
240 240
241 if (pdata && pdata->num_leds) { 241 if (pdata && pdata->num_leds) {
242 priv = devm_kzalloc(&pdev->dev, 242 priv = devm_kzalloc(&pdev->dev,
243 sizeof_gpio_leds_priv(pdata->num_leds), 243 sizeof_gpio_leds_priv(pdata->num_leds),
244 GFP_KERNEL); 244 GFP_KERNEL);
245 if (!priv) 245 if (!priv)
246 return -ENOMEM; 246 return -ENOMEM;
247 247
248 priv->num_leds = pdata->num_leds; 248 priv->num_leds = pdata->num_leds;
249 for (i = 0; i < priv->num_leds; i++) { 249 for (i = 0; i < priv->num_leds; i++) {
250 ret = create_gpio_led(&pdata->leds[i], 250 ret = create_gpio_led(&pdata->leds[i],
251 &priv->leds[i], 251 &priv->leds[i],
252 &pdev->dev, pdata->gpio_blink_set); 252 &pdev->dev, pdata->gpio_blink_set);
253 if (ret < 0) { 253 if (ret < 0) {
254 /* On failure: unwind the led creations */ 254 /* On failure: unwind the led creations */
255 for (i = i - 1; i >= 0; i--) 255 for (i = i - 1; i >= 0; i--)
256 delete_gpio_led(&priv->leds[i]); 256 delete_gpio_led(&priv->leds[i]);
257 return ret; 257 return ret;
258 } 258 }
259 } 259 }
260 } else { 260 } else {
261 priv = gpio_leds_create_of(pdev); 261 priv = gpio_leds_create_of(pdev);
262 if (IS_ERR(priv)) 262 if (IS_ERR(priv))
263 return PTR_ERR(priv); 263 return PTR_ERR(priv);
264 } 264 }
265 265
266 platform_set_drvdata(pdev, priv); 266 platform_set_drvdata(pdev, priv);
267 267
268 return 0; 268 return 0;
269 } 269 }
270 270
271 static int gpio_led_remove(struct platform_device *pdev) 271 static int gpio_led_remove(struct platform_device *pdev)
272 { 272 {
273 struct gpio_leds_priv *priv = platform_get_drvdata(pdev); 273 struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
274 int i; 274 int i;
275 275
276 for (i = 0; i < priv->num_leds; i++) 276 for (i = 0; i < priv->num_leds; i++)
277 delete_gpio_led(&priv->leds[i]); 277 delete_gpio_led(&priv->leds[i]);
278 278
279 return 0; 279 return 0;
280 } 280 }
281 281
282 static struct platform_driver gpio_led_driver = { 282 static struct platform_driver gpio_led_driver = {
283 .probe = gpio_led_probe, 283 .probe = gpio_led_probe,
284 .remove = gpio_led_remove, 284 .remove = gpio_led_remove,
285 .driver = { 285 .driver = {
286 .name = "leds-gpio", 286 .name = "leds-gpio",
287 .owner = THIS_MODULE, 287 .owner = THIS_MODULE,
288 .of_match_table = of_match_ptr(of_gpio_leds_match), 288 .of_match_table = of_match_ptr(of_gpio_leds_match),
289 }, 289 },
290 }; 290 };
291 291
292 module_platform_driver(gpio_led_driver); 292 module_platform_driver(gpio_led_driver);
293 293
294 MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>"); 294 MODULE_AUTHOR("Raphael Assenat <raph@8d.com>, Trent Piepho <tpiepho@freescale.com>");
295 MODULE_DESCRIPTION("GPIO LED driver"); 295 MODULE_DESCRIPTION("GPIO LED driver");
296 MODULE_LICENSE("GPL"); 296 MODULE_LICENSE("GPL");
297 MODULE_ALIAS("platform:leds-gpio"); 297 MODULE_ALIAS("platform:leds-gpio");
298 298
drivers/leds/leds-lm3530.c
1 /* 1 /*
2 * Copyright (C) 2011 ST-Ericsson SA. 2 * Copyright (C) 2011 ST-Ericsson SA.
3 * Copyright (C) 2009 Motorola, Inc. 3 * Copyright (C) 2009 Motorola, Inc.
4 * 4 *
5 * License Terms: GNU General Public License v2 5 * License Terms: GNU General Public License v2
6 * 6 *
7 * Simple driver for National Semiconductor LM3530 Backlight driver chip 7 * Simple driver for National Semiconductor LM3530 Backlight driver chip
8 * 8 *
9 * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com> 9 * Author: Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>
10 * based on leds-lm3530.c by Dan Murphy <D.Murphy@motorola.com> 10 * based on leds-lm3530.c by Dan Murphy <D.Murphy@motorola.com>
11 */ 11 */
12 12
13 #include <linux/i2c.h> 13 #include <linux/i2c.h>
14 #include <linux/leds.h> 14 #include <linux/leds.h>
15 #include <linux/slab.h> 15 #include <linux/slab.h>
16 #include <linux/platform_device.h> 16 #include <linux/platform_device.h>
17 #include <linux/input.h> 17 #include <linux/input.h>
18 #include <linux/led-lm3530.h> 18 #include <linux/led-lm3530.h>
19 #include <linux/types.h> 19 #include <linux/types.h>
20 #include <linux/regulator/consumer.h> 20 #include <linux/regulator/consumer.h>
21 #include <linux/module.h> 21 #include <linux/module.h>
22 22
23 #define LM3530_LED_DEV "lcd-backlight" 23 #define LM3530_LED_DEV "lcd-backlight"
24 #define LM3530_NAME "lm3530-led" 24 #define LM3530_NAME "lm3530-led"
25 25
26 #define LM3530_GEN_CONFIG 0x10 26 #define LM3530_GEN_CONFIG 0x10
27 #define LM3530_ALS_CONFIG 0x20 27 #define LM3530_ALS_CONFIG 0x20
28 #define LM3530_BRT_RAMP_RATE 0x30 28 #define LM3530_BRT_RAMP_RATE 0x30
29 #define LM3530_ALS_IMP_SELECT 0x41 29 #define LM3530_ALS_IMP_SELECT 0x41
30 #define LM3530_BRT_CTRL_REG 0xA0 30 #define LM3530_BRT_CTRL_REG 0xA0
31 #define LM3530_ALS_ZB0_REG 0x60 31 #define LM3530_ALS_ZB0_REG 0x60
32 #define LM3530_ALS_ZB1_REG 0x61 32 #define LM3530_ALS_ZB1_REG 0x61
33 #define LM3530_ALS_ZB2_REG 0x62 33 #define LM3530_ALS_ZB2_REG 0x62
34 #define LM3530_ALS_ZB3_REG 0x63 34 #define LM3530_ALS_ZB3_REG 0x63
35 #define LM3530_ALS_Z0T_REG 0x70 35 #define LM3530_ALS_Z0T_REG 0x70
36 #define LM3530_ALS_Z1T_REG 0x71 36 #define LM3530_ALS_Z1T_REG 0x71
37 #define LM3530_ALS_Z2T_REG 0x72 37 #define LM3530_ALS_Z2T_REG 0x72
38 #define LM3530_ALS_Z3T_REG 0x73 38 #define LM3530_ALS_Z3T_REG 0x73
39 #define LM3530_ALS_Z4T_REG 0x74 39 #define LM3530_ALS_Z4T_REG 0x74
40 #define LM3530_REG_MAX 14 40 #define LM3530_REG_MAX 14
41 41
42 /* General Control Register */ 42 /* General Control Register */
43 #define LM3530_EN_I2C_SHIFT (0) 43 #define LM3530_EN_I2C_SHIFT (0)
44 #define LM3530_RAMP_LAW_SHIFT (1) 44 #define LM3530_RAMP_LAW_SHIFT (1)
45 #define LM3530_MAX_CURR_SHIFT (2) 45 #define LM3530_MAX_CURR_SHIFT (2)
46 #define LM3530_EN_PWM_SHIFT (5) 46 #define LM3530_EN_PWM_SHIFT (5)
47 #define LM3530_PWM_POL_SHIFT (6) 47 #define LM3530_PWM_POL_SHIFT (6)
48 #define LM3530_EN_PWM_SIMPLE_SHIFT (7) 48 #define LM3530_EN_PWM_SIMPLE_SHIFT (7)
49 49
50 #define LM3530_ENABLE_I2C (1 << LM3530_EN_I2C_SHIFT) 50 #define LM3530_ENABLE_I2C (1 << LM3530_EN_I2C_SHIFT)
51 #define LM3530_ENABLE_PWM (1 << LM3530_EN_PWM_SHIFT) 51 #define LM3530_ENABLE_PWM (1 << LM3530_EN_PWM_SHIFT)
52 #define LM3530_POL_LOW (1 << LM3530_PWM_POL_SHIFT) 52 #define LM3530_POL_LOW (1 << LM3530_PWM_POL_SHIFT)
53 #define LM3530_ENABLE_PWM_SIMPLE (1 << LM3530_EN_PWM_SIMPLE_SHIFT) 53 #define LM3530_ENABLE_PWM_SIMPLE (1 << LM3530_EN_PWM_SIMPLE_SHIFT)
54 54
55 /* ALS Config Register Options */ 55 /* ALS Config Register Options */
56 #define LM3530_ALS_AVG_TIME_SHIFT (0) 56 #define LM3530_ALS_AVG_TIME_SHIFT (0)
57 #define LM3530_EN_ALS_SHIFT (3) 57 #define LM3530_EN_ALS_SHIFT (3)
58 #define LM3530_ALS_SEL_SHIFT (5) 58 #define LM3530_ALS_SEL_SHIFT (5)
59 59
60 #define LM3530_ENABLE_ALS (3 << LM3530_EN_ALS_SHIFT) 60 #define LM3530_ENABLE_ALS (3 << LM3530_EN_ALS_SHIFT)
61 61
62 /* Brightness Ramp Rate Register */ 62 /* Brightness Ramp Rate Register */
63 #define LM3530_BRT_RAMP_FALL_SHIFT (0) 63 #define LM3530_BRT_RAMP_FALL_SHIFT (0)
64 #define LM3530_BRT_RAMP_RISE_SHIFT (3) 64 #define LM3530_BRT_RAMP_RISE_SHIFT (3)
65 65
66 /* ALS Resistor Select */ 66 /* ALS Resistor Select */
67 #define LM3530_ALS1_IMP_SHIFT (0) 67 #define LM3530_ALS1_IMP_SHIFT (0)
68 #define LM3530_ALS2_IMP_SHIFT (4) 68 #define LM3530_ALS2_IMP_SHIFT (4)
69 69
70 /* Zone Boundary Register defaults */ 70 /* Zone Boundary Register defaults */
71 #define LM3530_ALS_ZB_MAX (4) 71 #define LM3530_ALS_ZB_MAX (4)
72 #define LM3530_ALS_WINDOW_mV (1000) 72 #define LM3530_ALS_WINDOW_mV (1000)
73 #define LM3530_ALS_OFFSET_mV (4) 73 #define LM3530_ALS_OFFSET_mV (4)
74 74
75 /* Zone Target Register defaults */ 75 /* Zone Target Register defaults */
76 #define LM3530_DEF_ZT_0 (0x7F) 76 #define LM3530_DEF_ZT_0 (0x7F)
77 #define LM3530_DEF_ZT_1 (0x66) 77 #define LM3530_DEF_ZT_1 (0x66)
78 #define LM3530_DEF_ZT_2 (0x4C) 78 #define LM3530_DEF_ZT_2 (0x4C)
79 #define LM3530_DEF_ZT_3 (0x33) 79 #define LM3530_DEF_ZT_3 (0x33)
80 #define LM3530_DEF_ZT_4 (0x19) 80 #define LM3530_DEF_ZT_4 (0x19)
81 81
82 /* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */ 82 /* 7 bits are used for the brightness : LM3530_BRT_CTRL_REG */
83 #define MAX_BRIGHTNESS (127) 83 #define MAX_BRIGHTNESS (127)
84 84
85 struct lm3530_mode_map { 85 struct lm3530_mode_map {
86 const char *mode; 86 const char *mode;
87 enum lm3530_mode mode_val; 87 enum lm3530_mode mode_val;
88 }; 88 };
89 89
90 static struct lm3530_mode_map mode_map[] = { 90 static struct lm3530_mode_map mode_map[] = {
91 { "man", LM3530_BL_MODE_MANUAL }, 91 { "man", LM3530_BL_MODE_MANUAL },
92 { "als", LM3530_BL_MODE_ALS }, 92 { "als", LM3530_BL_MODE_ALS },
93 { "pwm", LM3530_BL_MODE_PWM }, 93 { "pwm", LM3530_BL_MODE_PWM },
94 }; 94 };
95 95
96 /** 96 /**
97 * struct lm3530_data 97 * struct lm3530_data
98 * @led_dev: led class device 98 * @led_dev: led class device
99 * @client: i2c client 99 * @client: i2c client
100 * @pdata: LM3530 platform data 100 * @pdata: LM3530 platform data
101 * @mode: mode of operation - manual, ALS, PWM 101 * @mode: mode of operation - manual, ALS, PWM
102 * @regulator: regulator 102 * @regulator: regulator
103 * @brighness: previous brightness value 103 * @brighness: previous brightness value
104 * @enable: regulator is enabled 104 * @enable: regulator is enabled
105 */ 105 */
106 struct lm3530_data { 106 struct lm3530_data {
107 struct led_classdev led_dev; 107 struct led_classdev led_dev;
108 struct i2c_client *client; 108 struct i2c_client *client;
109 struct lm3530_platform_data *pdata; 109 struct lm3530_platform_data *pdata;
110 enum lm3530_mode mode; 110 enum lm3530_mode mode;
111 struct regulator *regulator; 111 struct regulator *regulator;
112 enum led_brightness brightness; 112 enum led_brightness brightness;
113 bool enable; 113 bool enable;
114 }; 114 };
115 115
116 /* 116 /*
117 * struct lm3530_als_data 117 * struct lm3530_als_data
118 * @config : value of ALS configuration register 118 * @config : value of ALS configuration register
119 * @imp_sel : value of ALS resistor select register 119 * @imp_sel : value of ALS resistor select register
120 * @zone : values of ALS ZB(Zone Boundary) registers 120 * @zone : values of ALS ZB(Zone Boundary) registers
121 */ 121 */
122 struct lm3530_als_data { 122 struct lm3530_als_data {
123 u8 config; 123 u8 config;
124 u8 imp_sel; 124 u8 imp_sel;
125 u8 zones[LM3530_ALS_ZB_MAX]; 125 u8 zones[LM3530_ALS_ZB_MAX];
126 }; 126 };
127 127
128 static const u8 lm3530_reg[LM3530_REG_MAX] = { 128 static const u8 lm3530_reg[LM3530_REG_MAX] = {
129 LM3530_GEN_CONFIG, 129 LM3530_GEN_CONFIG,
130 LM3530_ALS_CONFIG, 130 LM3530_ALS_CONFIG,
131 LM3530_BRT_RAMP_RATE, 131 LM3530_BRT_RAMP_RATE,
132 LM3530_ALS_IMP_SELECT, 132 LM3530_ALS_IMP_SELECT,
133 LM3530_BRT_CTRL_REG, 133 LM3530_BRT_CTRL_REG,
134 LM3530_ALS_ZB0_REG, 134 LM3530_ALS_ZB0_REG,
135 LM3530_ALS_ZB1_REG, 135 LM3530_ALS_ZB1_REG,
136 LM3530_ALS_ZB2_REG, 136 LM3530_ALS_ZB2_REG,
137 LM3530_ALS_ZB3_REG, 137 LM3530_ALS_ZB3_REG,
138 LM3530_ALS_Z0T_REG, 138 LM3530_ALS_Z0T_REG,
139 LM3530_ALS_Z1T_REG, 139 LM3530_ALS_Z1T_REG,
140 LM3530_ALS_Z2T_REG, 140 LM3530_ALS_Z2T_REG,
141 LM3530_ALS_Z3T_REG, 141 LM3530_ALS_Z3T_REG,
142 LM3530_ALS_Z4T_REG, 142 LM3530_ALS_Z4T_REG,
143 }; 143 };
144 144
145 static int lm3530_get_mode_from_str(const char *str) 145 static int lm3530_get_mode_from_str(const char *str)
146 { 146 {
147 int i; 147 int i;
148 148
149 for (i = 0; i < ARRAY_SIZE(mode_map); i++) 149 for (i = 0; i < ARRAY_SIZE(mode_map); i++)
150 if (sysfs_streq(str, mode_map[i].mode)) 150 if (sysfs_streq(str, mode_map[i].mode))
151 return mode_map[i].mode_val; 151 return mode_map[i].mode_val;
152 152
153 return -EINVAL; 153 return -EINVAL;
154 } 154 }
155 155
156 static void lm3530_als_configure(struct lm3530_platform_data *pdata, 156 static void lm3530_als_configure(struct lm3530_platform_data *pdata,
157 struct lm3530_als_data *als) 157 struct lm3530_als_data *als)
158 { 158 {
159 int i; 159 int i;
160 u32 als_vmin, als_vmax, als_vstep; 160 u32 als_vmin, als_vmax, als_vstep;
161 161
162 if (pdata->als_vmax == 0) { 162 if (pdata->als_vmax == 0) {
163 pdata->als_vmin = 0; 163 pdata->als_vmin = 0;
164 pdata->als_vmax = LM3530_ALS_WINDOW_mV; 164 pdata->als_vmax = LM3530_ALS_WINDOW_mV;
165 } 165 }
166 166
167 als_vmin = pdata->als_vmin; 167 als_vmin = pdata->als_vmin;
168 als_vmax = pdata->als_vmax; 168 als_vmax = pdata->als_vmax;
169 169
170 if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV) 170 if ((als_vmax - als_vmin) > LM3530_ALS_WINDOW_mV)
171 pdata->als_vmax = als_vmax = als_vmin + LM3530_ALS_WINDOW_mV; 171 pdata->als_vmax = als_vmax = als_vmin + LM3530_ALS_WINDOW_mV;
172 172
173 /* n zone boundary makes n+1 zones */ 173 /* n zone boundary makes n+1 zones */
174 als_vstep = (als_vmax - als_vmin) / (LM3530_ALS_ZB_MAX + 1); 174 als_vstep = (als_vmax - als_vmin) / (LM3530_ALS_ZB_MAX + 1);
175 175
176 for (i = 0; i < LM3530_ALS_ZB_MAX; i++) 176 for (i = 0; i < LM3530_ALS_ZB_MAX; i++)
177 als->zones[i] = (((als_vmin + LM3530_ALS_OFFSET_mV) + 177 als->zones[i] = (((als_vmin + LM3530_ALS_OFFSET_mV) +
178 als_vstep + (i * als_vstep)) * LED_FULL) / 1000; 178 als_vstep + (i * als_vstep)) * LED_FULL) / 1000;
179 179
180 als->config = 180 als->config =
181 (pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) | 181 (pdata->als_avrg_time << LM3530_ALS_AVG_TIME_SHIFT) |
182 (LM3530_ENABLE_ALS) | 182 (LM3530_ENABLE_ALS) |
183 (pdata->als_input_mode << LM3530_ALS_SEL_SHIFT); 183 (pdata->als_input_mode << LM3530_ALS_SEL_SHIFT);
184 184
185 als->imp_sel = 185 als->imp_sel =
186 (pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) | 186 (pdata->als1_resistor_sel << LM3530_ALS1_IMP_SHIFT) |
187 (pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT); 187 (pdata->als2_resistor_sel << LM3530_ALS2_IMP_SHIFT);
188 } 188 }
189 189
190 static int lm3530_led_enable(struct lm3530_data *drvdata) 190 static int lm3530_led_enable(struct lm3530_data *drvdata)
191 { 191 {
192 int ret; 192 int ret;
193 193
194 if (drvdata->enable) 194 if (drvdata->enable)
195 return 0; 195 return 0;
196 196
197 ret = regulator_enable(drvdata->regulator); 197 ret = regulator_enable(drvdata->regulator);
198 if (ret) { 198 if (ret) {
199 dev_err(drvdata->led_dev.dev, "Failed to enable vin:%d\n", ret); 199 dev_err(drvdata->led_dev.dev, "Failed to enable vin:%d\n", ret);
200 return ret; 200 return ret;
201 } 201 }
202 202
203 drvdata->enable = true; 203 drvdata->enable = true;
204 return 0; 204 return 0;
205 } 205 }
206 206
207 static void lm3530_led_disable(struct lm3530_data *drvdata) 207 static void lm3530_led_disable(struct lm3530_data *drvdata)
208 { 208 {
209 int ret; 209 int ret;
210 210
211 if (!drvdata->enable) 211 if (!drvdata->enable)
212 return; 212 return;
213 213
214 ret = regulator_disable(drvdata->regulator); 214 ret = regulator_disable(drvdata->regulator);
215 if (ret) { 215 if (ret) {
216 dev_err(drvdata->led_dev.dev, "Failed to disable vin:%d\n", 216 dev_err(drvdata->led_dev.dev, "Failed to disable vin:%d\n",
217 ret); 217 ret);
218 return; 218 return;
219 } 219 }
220 220
221 drvdata->enable = false; 221 drvdata->enable = false;
222 } 222 }
223 223
224 static int lm3530_init_registers(struct lm3530_data *drvdata) 224 static int lm3530_init_registers(struct lm3530_data *drvdata)
225 { 225 {
226 int ret = 0; 226 int ret = 0;
227 int i; 227 int i;
228 u8 gen_config; 228 u8 gen_config;
229 u8 brt_ramp; 229 u8 brt_ramp;
230 u8 brightness; 230 u8 brightness;
231 u8 reg_val[LM3530_REG_MAX]; 231 u8 reg_val[LM3530_REG_MAX];
232 struct lm3530_platform_data *pdata = drvdata->pdata; 232 struct lm3530_platform_data *pdata = drvdata->pdata;
233 struct i2c_client *client = drvdata->client; 233 struct i2c_client *client = drvdata->client;
234 struct lm3530_pwm_data *pwm = &pdata->pwm_data; 234 struct lm3530_pwm_data *pwm = &pdata->pwm_data;
235 struct lm3530_als_data als; 235 struct lm3530_als_data als;
236 236
237 memset(&als, 0, sizeof(struct lm3530_als_data)); 237 memset(&als, 0, sizeof(struct lm3530_als_data));
238 238
239 gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) | 239 gen_config = (pdata->brt_ramp_law << LM3530_RAMP_LAW_SHIFT) |
240 ((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT); 240 ((pdata->max_current & 7) << LM3530_MAX_CURR_SHIFT);
241 241
242 switch (drvdata->mode) { 242 switch (drvdata->mode) {
243 case LM3530_BL_MODE_MANUAL: 243 case LM3530_BL_MODE_MANUAL:
244 gen_config |= LM3530_ENABLE_I2C; 244 gen_config |= LM3530_ENABLE_I2C;
245 break; 245 break;
246 case LM3530_BL_MODE_ALS: 246 case LM3530_BL_MODE_ALS:
247 gen_config |= LM3530_ENABLE_I2C; 247 gen_config |= LM3530_ENABLE_I2C;
248 lm3530_als_configure(pdata, &als); 248 lm3530_als_configure(pdata, &als);
249 break; 249 break;
250 case LM3530_BL_MODE_PWM: 250 case LM3530_BL_MODE_PWM:
251 gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE | 251 gen_config |= LM3530_ENABLE_PWM | LM3530_ENABLE_PWM_SIMPLE |
252 (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT); 252 (pdata->pwm_pol_hi << LM3530_PWM_POL_SHIFT);
253 break; 253 break;
254 } 254 }
255 255
256 brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) | 256 brt_ramp = (pdata->brt_ramp_fall << LM3530_BRT_RAMP_FALL_SHIFT) |
257 (pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT); 257 (pdata->brt_ramp_rise << LM3530_BRT_RAMP_RISE_SHIFT);
258 258
259 if (drvdata->brightness) 259 if (drvdata->brightness)
260 brightness = drvdata->brightness; 260 brightness = drvdata->brightness;
261 else 261 else
262 brightness = drvdata->brightness = pdata->brt_val; 262 brightness = drvdata->brightness = pdata->brt_val;
263 263
264 if (brightness > drvdata->led_dev.max_brightness) 264 if (brightness > drvdata->led_dev.max_brightness)
265 brightness = drvdata->led_dev.max_brightness; 265 brightness = drvdata->led_dev.max_brightness;
266 266
267 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */ 267 reg_val[0] = gen_config; /* LM3530_GEN_CONFIG */
268 reg_val[1] = als.config; /* LM3530_ALS_CONFIG */ 268 reg_val[1] = als.config; /* LM3530_ALS_CONFIG */
269 reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */ 269 reg_val[2] = brt_ramp; /* LM3530_BRT_RAMP_RATE */
270 reg_val[3] = als.imp_sel; /* LM3530_ALS_IMP_SELECT */ 270 reg_val[3] = als.imp_sel; /* LM3530_ALS_IMP_SELECT */
271 reg_val[4] = brightness; /* LM3530_BRT_CTRL_REG */ 271 reg_val[4] = brightness; /* LM3530_BRT_CTRL_REG */
272 reg_val[5] = als.zones[0]; /* LM3530_ALS_ZB0_REG */ 272 reg_val[5] = als.zones[0]; /* LM3530_ALS_ZB0_REG */
273 reg_val[6] = als.zones[1]; /* LM3530_ALS_ZB1_REG */ 273 reg_val[6] = als.zones[1]; /* LM3530_ALS_ZB1_REG */
274 reg_val[7] = als.zones[2]; /* LM3530_ALS_ZB2_REG */ 274 reg_val[7] = als.zones[2]; /* LM3530_ALS_ZB2_REG */
275 reg_val[8] = als.zones[3]; /* LM3530_ALS_ZB3_REG */ 275 reg_val[8] = als.zones[3]; /* LM3530_ALS_ZB3_REG */
276 reg_val[9] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */ 276 reg_val[9] = LM3530_DEF_ZT_0; /* LM3530_ALS_Z0T_REG */
277 reg_val[10] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */ 277 reg_val[10] = LM3530_DEF_ZT_1; /* LM3530_ALS_Z1T_REG */
278 reg_val[11] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */ 278 reg_val[11] = LM3530_DEF_ZT_2; /* LM3530_ALS_Z2T_REG */
279 reg_val[12] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */ 279 reg_val[12] = LM3530_DEF_ZT_3; /* LM3530_ALS_Z3T_REG */
280 reg_val[13] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */ 280 reg_val[13] = LM3530_DEF_ZT_4; /* LM3530_ALS_Z4T_REG */
281 281
282 ret = lm3530_led_enable(drvdata); 282 ret = lm3530_led_enable(drvdata);
283 if (ret) 283 if (ret)
284 return ret; 284 return ret;
285 285
286 for (i = 0; i < LM3530_REG_MAX; i++) { 286 for (i = 0; i < LM3530_REG_MAX; i++) {
287 /* do not update brightness register when pwm mode */ 287 /* do not update brightness register when pwm mode */
288 if (lm3530_reg[i] == LM3530_BRT_CTRL_REG && 288 if (lm3530_reg[i] == LM3530_BRT_CTRL_REG &&
289 drvdata->mode == LM3530_BL_MODE_PWM) { 289 drvdata->mode == LM3530_BL_MODE_PWM) {
290 if (pwm->pwm_set_intensity) 290 if (pwm->pwm_set_intensity)
291 pwm->pwm_set_intensity(reg_val[i], 291 pwm->pwm_set_intensity(reg_val[i],
292 drvdata->led_dev.max_brightness); 292 drvdata->led_dev.max_brightness);
293 continue; 293 continue;
294 } 294 }
295 295
296 ret = i2c_smbus_write_byte_data(client, 296 ret = i2c_smbus_write_byte_data(client,
297 lm3530_reg[i], reg_val[i]); 297 lm3530_reg[i], reg_val[i]);
298 if (ret) 298 if (ret)
299 break; 299 break;
300 } 300 }
301 301
302 return ret; 302 return ret;
303 } 303 }
304 304
305 static void lm3530_brightness_set(struct led_classdev *led_cdev, 305 static void lm3530_brightness_set(struct led_classdev *led_cdev,
306 enum led_brightness brt_val) 306 enum led_brightness brt_val)
307 { 307 {
308 int err; 308 int err;
309 struct lm3530_data *drvdata = 309 struct lm3530_data *drvdata =
310 container_of(led_cdev, struct lm3530_data, led_dev); 310 container_of(led_cdev, struct lm3530_data, led_dev);
311 struct lm3530_platform_data *pdata = drvdata->pdata; 311 struct lm3530_platform_data *pdata = drvdata->pdata;
312 struct lm3530_pwm_data *pwm = &pdata->pwm_data; 312 struct lm3530_pwm_data *pwm = &pdata->pwm_data;
313 u8 max_brightness = led_cdev->max_brightness; 313 u8 max_brightness = led_cdev->max_brightness;
314 314
315 switch (drvdata->mode) { 315 switch (drvdata->mode) {
316 case LM3530_BL_MODE_MANUAL: 316 case LM3530_BL_MODE_MANUAL:
317 317
318 if (!drvdata->enable) { 318 if (!drvdata->enable) {
319 err = lm3530_init_registers(drvdata); 319 err = lm3530_init_registers(drvdata);
320 if (err) { 320 if (err) {
321 dev_err(&drvdata->client->dev, 321 dev_err(&drvdata->client->dev,
322 "Register Init failed: %d\n", err); 322 "Register Init failed: %d\n", err);
323 break; 323 break;
324 } 324 }
325 } 325 }
326 326
327 /* set the brightness in brightness control register*/ 327 /* set the brightness in brightness control register*/
328 err = i2c_smbus_write_byte_data(drvdata->client, 328 err = i2c_smbus_write_byte_data(drvdata->client,
329 LM3530_BRT_CTRL_REG, brt_val); 329 LM3530_BRT_CTRL_REG, brt_val);
330 if (err) 330 if (err)
331 dev_err(&drvdata->client->dev, 331 dev_err(&drvdata->client->dev,
332 "Unable to set brightness: %d\n", err); 332 "Unable to set brightness: %d\n", err);
333 else 333 else
334 drvdata->brightness = brt_val; 334 drvdata->brightness = brt_val;
335 335
336 if (brt_val == 0) 336 if (brt_val == 0)
337 lm3530_led_disable(drvdata); 337 lm3530_led_disable(drvdata);
338 break; 338 break;
339 case LM3530_BL_MODE_ALS: 339 case LM3530_BL_MODE_ALS:
340 break; 340 break;
341 case LM3530_BL_MODE_PWM: 341 case LM3530_BL_MODE_PWM:
342 if (pwm->pwm_set_intensity) 342 if (pwm->pwm_set_intensity)
343 pwm->pwm_set_intensity(brt_val, max_brightness); 343 pwm->pwm_set_intensity(brt_val, max_brightness);
344 break; 344 break;
345 default: 345 default:
346 break; 346 break;
347 } 347 }
348 } 348 }
349 349
350 static ssize_t lm3530_mode_get(struct device *dev, 350 static ssize_t lm3530_mode_get(struct device *dev,
351 struct device_attribute *attr, char *buf) 351 struct device_attribute *attr, char *buf)
352 { 352 {
353 struct led_classdev *led_cdev = dev_get_drvdata(dev); 353 struct led_classdev *led_cdev = dev_get_drvdata(dev);
354 struct lm3530_data *drvdata; 354 struct lm3530_data *drvdata;
355 int i, len = 0; 355 int i, len = 0;
356 356
357 drvdata = container_of(led_cdev, struct lm3530_data, led_dev); 357 drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
358 for (i = 0; i < ARRAY_SIZE(mode_map); i++) 358 for (i = 0; i < ARRAY_SIZE(mode_map); i++)
359 if (drvdata->mode == mode_map[i].mode_val) 359 if (drvdata->mode == mode_map[i].mode_val)
360 len += sprintf(buf + len, "[%s] ", mode_map[i].mode); 360 len += sprintf(buf + len, "[%s] ", mode_map[i].mode);
361 else 361 else
362 len += sprintf(buf + len, "%s ", mode_map[i].mode); 362 len += sprintf(buf + len, "%s ", mode_map[i].mode);
363 363
364 len += sprintf(buf + len, "\n"); 364 len += sprintf(buf + len, "\n");
365 365
366 return len; 366 return len;
367 } 367 }
368 368
369 static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute 369 static ssize_t lm3530_mode_set(struct device *dev, struct device_attribute
370 *attr, const char *buf, size_t size) 370 *attr, const char *buf, size_t size)
371 { 371 {
372 struct led_classdev *led_cdev = dev_get_drvdata(dev); 372 struct led_classdev *led_cdev = dev_get_drvdata(dev);
373 struct lm3530_data *drvdata; 373 struct lm3530_data *drvdata;
374 struct lm3530_pwm_data *pwm; 374 struct lm3530_pwm_data *pwm;
375 u8 max_brightness; 375 u8 max_brightness;
376 int mode, err; 376 int mode, err;
377 377
378 drvdata = container_of(led_cdev, struct lm3530_data, led_dev); 378 drvdata = container_of(led_cdev, struct lm3530_data, led_dev);
379 pwm = &drvdata->pdata->pwm_data; 379 pwm = &drvdata->pdata->pwm_data;
380 max_brightness = led_cdev->max_brightness; 380 max_brightness = led_cdev->max_brightness;
381 mode = lm3530_get_mode_from_str(buf); 381 mode = lm3530_get_mode_from_str(buf);
382 if (mode < 0) { 382 if (mode < 0) {
383 dev_err(dev, "Invalid mode\n"); 383 dev_err(dev, "Invalid mode\n");
384 return mode; 384 return mode;
385 } 385 }
386 386
387 drvdata->mode = mode; 387 drvdata->mode = mode;
388 388
389 /* set pwm to low if unnecessary */ 389 /* set pwm to low if unnecessary */
390 if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity) 390 if (mode != LM3530_BL_MODE_PWM && pwm->pwm_set_intensity)
391 pwm->pwm_set_intensity(0, max_brightness); 391 pwm->pwm_set_intensity(0, max_brightness);
392 392
393 err = lm3530_init_registers(drvdata); 393 err = lm3530_init_registers(drvdata);
394 if (err) { 394 if (err) {
395 dev_err(dev, "Setting %s Mode failed :%d\n", buf, err); 395 dev_err(dev, "Setting %s Mode failed :%d\n", buf, err);
396 return err; 396 return err;
397 } 397 }
398 398
399 return sizeof(drvdata->mode); 399 return sizeof(drvdata->mode);
400 } 400 }
401 static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set); 401 static DEVICE_ATTR(mode, 0644, lm3530_mode_get, lm3530_mode_set);
402 402
403 static int lm3530_probe(struct i2c_client *client, 403 static int lm3530_probe(struct i2c_client *client,
404 const struct i2c_device_id *id) 404 const struct i2c_device_id *id)
405 { 405 {
406 struct lm3530_platform_data *pdata = client->dev.platform_data; 406 struct lm3530_platform_data *pdata = dev_get_platdata(&client->dev);
407 struct lm3530_data *drvdata; 407 struct lm3530_data *drvdata;
408 int err = 0; 408 int err = 0;
409 409
410 if (pdata == NULL) { 410 if (pdata == NULL) {
411 dev_err(&client->dev, "platform data required\n"); 411 dev_err(&client->dev, "platform data required\n");
412 return -ENODEV; 412 return -ENODEV;
413 } 413 }
414 414
415 /* BL mode */ 415 /* BL mode */
416 if (pdata->mode > LM3530_BL_MODE_PWM) { 416 if (pdata->mode > LM3530_BL_MODE_PWM) {
417 dev_err(&client->dev, "Illegal Mode request\n"); 417 dev_err(&client->dev, "Illegal Mode request\n");
418 return -EINVAL; 418 return -EINVAL;
419 } 419 }
420 420
421 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 421 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
422 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n"); 422 dev_err(&client->dev, "I2C_FUNC_I2C not supported\n");
423 return -EIO; 423 return -EIO;
424 } 424 }
425 425
426 drvdata = devm_kzalloc(&client->dev, sizeof(struct lm3530_data), 426 drvdata = devm_kzalloc(&client->dev, sizeof(struct lm3530_data),
427 GFP_KERNEL); 427 GFP_KERNEL);
428 if (drvdata == NULL) 428 if (drvdata == NULL)
429 return -ENOMEM; 429 return -ENOMEM;
430 430
431 drvdata->mode = pdata->mode; 431 drvdata->mode = pdata->mode;
432 drvdata->client = client; 432 drvdata->client = client;
433 drvdata->pdata = pdata; 433 drvdata->pdata = pdata;
434 drvdata->brightness = LED_OFF; 434 drvdata->brightness = LED_OFF;
435 drvdata->enable = false; 435 drvdata->enable = false;
436 drvdata->led_dev.name = LM3530_LED_DEV; 436 drvdata->led_dev.name = LM3530_LED_DEV;
437 drvdata->led_dev.brightness_set = lm3530_brightness_set; 437 drvdata->led_dev.brightness_set = lm3530_brightness_set;
438 drvdata->led_dev.max_brightness = MAX_BRIGHTNESS; 438 drvdata->led_dev.max_brightness = MAX_BRIGHTNESS;
439 439
440 i2c_set_clientdata(client, drvdata); 440 i2c_set_clientdata(client, drvdata);
441 441
442 drvdata->regulator = devm_regulator_get(&client->dev, "vin"); 442 drvdata->regulator = devm_regulator_get(&client->dev, "vin");
443 if (IS_ERR(drvdata->regulator)) { 443 if (IS_ERR(drvdata->regulator)) {
444 dev_err(&client->dev, "regulator get failed\n"); 444 dev_err(&client->dev, "regulator get failed\n");
445 err = PTR_ERR(drvdata->regulator); 445 err = PTR_ERR(drvdata->regulator);
446 drvdata->regulator = NULL; 446 drvdata->regulator = NULL;
447 return err; 447 return err;
448 } 448 }
449 449
450 if (drvdata->pdata->brt_val) { 450 if (drvdata->pdata->brt_val) {
451 err = lm3530_init_registers(drvdata); 451 err = lm3530_init_registers(drvdata);
452 if (err < 0) { 452 if (err < 0) {
453 dev_err(&client->dev, 453 dev_err(&client->dev,
454 "Register Init failed: %d\n", err); 454 "Register Init failed: %d\n", err);
455 return err; 455 return err;
456 } 456 }
457 } 457 }
458 err = led_classdev_register(&client->dev, &drvdata->led_dev); 458 err = led_classdev_register(&client->dev, &drvdata->led_dev);
459 if (err < 0) { 459 if (err < 0) {
460 dev_err(&client->dev, "Register led class failed: %d\n", err); 460 dev_err(&client->dev, "Register led class failed: %d\n", err);
461 return err; 461 return err;
462 } 462 }
463 463
464 err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode); 464 err = device_create_file(drvdata->led_dev.dev, &dev_attr_mode);
465 if (err < 0) { 465 if (err < 0) {
466 dev_err(&client->dev, "File device creation failed: %d\n", err); 466 dev_err(&client->dev, "File device creation failed: %d\n", err);
467 err = -ENODEV; 467 err = -ENODEV;
468 goto err_create_file; 468 goto err_create_file;
469 } 469 }
470 470
471 return 0; 471 return 0;
472 472
473 err_create_file: 473 err_create_file:
474 led_classdev_unregister(&drvdata->led_dev); 474 led_classdev_unregister(&drvdata->led_dev);
475 return err; 475 return err;
476 } 476 }
477 477
478 static int lm3530_remove(struct i2c_client *client) 478 static int lm3530_remove(struct i2c_client *client)
479 { 479 {
480 struct lm3530_data *drvdata = i2c_get_clientdata(client); 480 struct lm3530_data *drvdata = i2c_get_clientdata(client);
481 481
482 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode); 482 device_remove_file(drvdata->led_dev.dev, &dev_attr_mode);
483 483
484 lm3530_led_disable(drvdata); 484 lm3530_led_disable(drvdata);
485 led_classdev_unregister(&drvdata->led_dev); 485 led_classdev_unregister(&drvdata->led_dev);
486 return 0; 486 return 0;
487 } 487 }
488 488
489 static const struct i2c_device_id lm3530_id[] = { 489 static const struct i2c_device_id lm3530_id[] = {
490 {LM3530_NAME, 0}, 490 {LM3530_NAME, 0},
491 {} 491 {}
492 }; 492 };
493 MODULE_DEVICE_TABLE(i2c, lm3530_id); 493 MODULE_DEVICE_TABLE(i2c, lm3530_id);
494 494
495 static struct i2c_driver lm3530_i2c_driver = { 495 static struct i2c_driver lm3530_i2c_driver = {
496 .probe = lm3530_probe, 496 .probe = lm3530_probe,
497 .remove = lm3530_remove, 497 .remove = lm3530_remove,
498 .id_table = lm3530_id, 498 .id_table = lm3530_id,
499 .driver = { 499 .driver = {
500 .name = LM3530_NAME, 500 .name = LM3530_NAME,
501 .owner = THIS_MODULE, 501 .owner = THIS_MODULE,
502 }, 502 },
503 }; 503 };
504 504
505 module_i2c_driver(lm3530_i2c_driver); 505 module_i2c_driver(lm3530_i2c_driver);
506 506
507 MODULE_DESCRIPTION("Back Light driver for LM3530"); 507 MODULE_DESCRIPTION("Back Light driver for LM3530");
508 MODULE_LICENSE("GPL v2"); 508 MODULE_LICENSE("GPL v2");
509 MODULE_AUTHOR("Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>"); 509 MODULE_AUTHOR("Shreshtha Kumar SAHU <shreshthakumar.sahu@stericsson.com>");
510 510
drivers/leds/leds-lm3533.c
1 /* 1 /*
2 * leds-lm3533.c -- LM3533 LED driver 2 * leds-lm3533.c -- LM3533 LED driver
3 * 3 *
4 * Copyright (C) 2011-2012 Texas Instruments 4 * Copyright (C) 2011-2012 Texas Instruments
5 * 5 *
6 * Author: Johan Hovold <jhovold@gmail.com> 6 * Author: Johan Hovold <jhovold@gmail.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify it 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 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 10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. 11 * option) any later version.
12 */ 12 */
13 13
14 #include <linux/module.h> 14 #include <linux/module.h>
15 #include <linux/init.h> 15 #include <linux/init.h>
16 #include <linux/leds.h> 16 #include <linux/leds.h>
17 #include <linux/mfd/core.h> 17 #include <linux/mfd/core.h>
18 #include <linux/mutex.h> 18 #include <linux/mutex.h>
19 #include <linux/platform_device.h> 19 #include <linux/platform_device.h>
20 #include <linux/slab.h> 20 #include <linux/slab.h>
21 #include <linux/workqueue.h> 21 #include <linux/workqueue.h>
22 22
23 #include <linux/mfd/lm3533.h> 23 #include <linux/mfd/lm3533.h>
24 24
25 25
26 #define LM3533_LVCTRLBANK_MIN 2 26 #define LM3533_LVCTRLBANK_MIN 2
27 #define LM3533_LVCTRLBANK_MAX 5 27 #define LM3533_LVCTRLBANK_MAX 5
28 #define LM3533_LVCTRLBANK_COUNT 4 28 #define LM3533_LVCTRLBANK_COUNT 4
29 #define LM3533_RISEFALLTIME_MAX 7 29 #define LM3533_RISEFALLTIME_MAX 7
30 #define LM3533_ALS_CHANNEL_LV_MIN 1 30 #define LM3533_ALS_CHANNEL_LV_MIN 1
31 #define LM3533_ALS_CHANNEL_LV_MAX 2 31 #define LM3533_ALS_CHANNEL_LV_MAX 2
32 32
33 #define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b 33 #define LM3533_REG_CTRLBANK_BCONF_BASE 0x1b
34 #define LM3533_REG_PATTERN_ENABLE 0x28 34 #define LM3533_REG_PATTERN_ENABLE 0x28
35 #define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71 35 #define LM3533_REG_PATTERN_LOW_TIME_BASE 0x71
36 #define LM3533_REG_PATTERN_HIGH_TIME_BASE 0x72 36 #define LM3533_REG_PATTERN_HIGH_TIME_BASE 0x72
37 #define LM3533_REG_PATTERN_RISETIME_BASE 0x74 37 #define LM3533_REG_PATTERN_RISETIME_BASE 0x74
38 #define LM3533_REG_PATTERN_FALLTIME_BASE 0x75 38 #define LM3533_REG_PATTERN_FALLTIME_BASE 0x75
39 39
40 #define LM3533_REG_PATTERN_STEP 0x10 40 #define LM3533_REG_PATTERN_STEP 0x10
41 41
42 #define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK 0x04 42 #define LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK 0x04
43 #define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK 0x02 43 #define LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK 0x02
44 #define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK 0x01 44 #define LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK 0x01
45 45
46 #define LM3533_LED_FLAG_PATTERN_ENABLE 1 46 #define LM3533_LED_FLAG_PATTERN_ENABLE 1
47 47
48 48
49 struct lm3533_led { 49 struct lm3533_led {
50 struct lm3533 *lm3533; 50 struct lm3533 *lm3533;
51 struct lm3533_ctrlbank cb; 51 struct lm3533_ctrlbank cb;
52 struct led_classdev cdev; 52 struct led_classdev cdev;
53 int id; 53 int id;
54 54
55 struct mutex mutex; 55 struct mutex mutex;
56 unsigned long flags; 56 unsigned long flags;
57 57
58 struct work_struct work; 58 struct work_struct work;
59 u8 new_brightness; 59 u8 new_brightness;
60 }; 60 };
61 61
62 62
63 static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev) 63 static inline struct lm3533_led *to_lm3533_led(struct led_classdev *cdev)
64 { 64 {
65 return container_of(cdev, struct lm3533_led, cdev); 65 return container_of(cdev, struct lm3533_led, cdev);
66 } 66 }
67 67
68 static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led) 68 static inline int lm3533_led_get_ctrlbank_id(struct lm3533_led *led)
69 { 69 {
70 return led->id + 2; 70 return led->id + 2;
71 } 71 }
72 72
73 static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base) 73 static inline u8 lm3533_led_get_lv_reg(struct lm3533_led *led, u8 base)
74 { 74 {
75 return base + led->id; 75 return base + led->id;
76 } 76 }
77 77
78 static inline u8 lm3533_led_get_pattern(struct lm3533_led *led) 78 static inline u8 lm3533_led_get_pattern(struct lm3533_led *led)
79 { 79 {
80 return led->id; 80 return led->id;
81 } 81 }
82 82
83 static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led, 83 static inline u8 lm3533_led_get_pattern_reg(struct lm3533_led *led,
84 u8 base) 84 u8 base)
85 { 85 {
86 return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP; 86 return base + lm3533_led_get_pattern(led) * LM3533_REG_PATTERN_STEP;
87 } 87 }
88 88
89 static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable) 89 static int lm3533_led_pattern_enable(struct lm3533_led *led, int enable)
90 { 90 {
91 u8 mask; 91 u8 mask;
92 u8 val; 92 u8 val;
93 int pattern; 93 int pattern;
94 int state; 94 int state;
95 int ret = 0; 95 int ret = 0;
96 96
97 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable); 97 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, enable);
98 98
99 mutex_lock(&led->mutex); 99 mutex_lock(&led->mutex);
100 100
101 state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags); 101 state = test_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
102 if ((enable && state) || (!enable && !state)) 102 if ((enable && state) || (!enable && !state))
103 goto out; 103 goto out;
104 104
105 pattern = lm3533_led_get_pattern(led); 105 pattern = lm3533_led_get_pattern(led);
106 mask = 1 << (2 * pattern); 106 mask = 1 << (2 * pattern);
107 107
108 if (enable) 108 if (enable)
109 val = mask; 109 val = mask;
110 else 110 else
111 val = 0; 111 val = 0;
112 112
113 ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask); 113 ret = lm3533_update(led->lm3533, LM3533_REG_PATTERN_ENABLE, val, mask);
114 if (ret) { 114 if (ret) {
115 dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n", 115 dev_err(led->cdev.dev, "failed to enable pattern %d (%d)\n",
116 pattern, enable); 116 pattern, enable);
117 goto out; 117 goto out;
118 } 118 }
119 119
120 __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags); 120 __change_bit(LM3533_LED_FLAG_PATTERN_ENABLE, &led->flags);
121 out: 121 out:
122 mutex_unlock(&led->mutex); 122 mutex_unlock(&led->mutex);
123 123
124 return ret; 124 return ret;
125 } 125 }
126 126
127 static void lm3533_led_work(struct work_struct *work) 127 static void lm3533_led_work(struct work_struct *work)
128 { 128 {
129 struct lm3533_led *led = container_of(work, struct lm3533_led, work); 129 struct lm3533_led *led = container_of(work, struct lm3533_led, work);
130 130
131 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, led->new_brightness); 131 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, led->new_brightness);
132 132
133 if (led->new_brightness == 0) 133 if (led->new_brightness == 0)
134 lm3533_led_pattern_enable(led, 0); /* disable blink */ 134 lm3533_led_pattern_enable(led, 0); /* disable blink */
135 135
136 lm3533_ctrlbank_set_brightness(&led->cb, led->new_brightness); 136 lm3533_ctrlbank_set_brightness(&led->cb, led->new_brightness);
137 } 137 }
138 138
139 static void lm3533_led_set(struct led_classdev *cdev, 139 static void lm3533_led_set(struct led_classdev *cdev,
140 enum led_brightness value) 140 enum led_brightness value)
141 { 141 {
142 struct lm3533_led *led = to_lm3533_led(cdev); 142 struct lm3533_led *led = to_lm3533_led(cdev);
143 143
144 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value); 144 dev_dbg(led->cdev.dev, "%s - %d\n", __func__, value);
145 145
146 led->new_brightness = value; 146 led->new_brightness = value;
147 schedule_work(&led->work); 147 schedule_work(&led->work);
148 } 148 }
149 149
150 static enum led_brightness lm3533_led_get(struct led_classdev *cdev) 150 static enum led_brightness lm3533_led_get(struct led_classdev *cdev)
151 { 151 {
152 struct lm3533_led *led = to_lm3533_led(cdev); 152 struct lm3533_led *led = to_lm3533_led(cdev);
153 u8 val; 153 u8 val;
154 int ret; 154 int ret;
155 155
156 ret = lm3533_ctrlbank_get_brightness(&led->cb, &val); 156 ret = lm3533_ctrlbank_get_brightness(&led->cb, &val);
157 if (ret) 157 if (ret)
158 return ret; 158 return ret;
159 159
160 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val); 160 dev_dbg(led->cdev.dev, "%s - %u\n", __func__, val);
161 161
162 return val; 162 return val;
163 } 163 }
164 164
165 /* Pattern generator defines (delays in us). */ 165 /* Pattern generator defines (delays in us). */
166 #define LM3533_LED_DELAY1_VMIN 0x00 166 #define LM3533_LED_DELAY1_VMIN 0x00
167 #define LM3533_LED_DELAY2_VMIN 0x3d 167 #define LM3533_LED_DELAY2_VMIN 0x3d
168 #define LM3533_LED_DELAY3_VMIN 0x80 168 #define LM3533_LED_DELAY3_VMIN 0x80
169 169
170 #define LM3533_LED_DELAY1_VMAX (LM3533_LED_DELAY2_VMIN - 1) 170 #define LM3533_LED_DELAY1_VMAX (LM3533_LED_DELAY2_VMIN - 1)
171 #define LM3533_LED_DELAY2_VMAX (LM3533_LED_DELAY3_VMIN - 1) 171 #define LM3533_LED_DELAY2_VMAX (LM3533_LED_DELAY3_VMIN - 1)
172 #define LM3533_LED_DELAY3_VMAX 0xff 172 #define LM3533_LED_DELAY3_VMAX 0xff
173 173
174 #define LM3533_LED_DELAY1_TMIN 16384U 174 #define LM3533_LED_DELAY1_TMIN 16384U
175 #define LM3533_LED_DELAY2_TMIN 1130496U 175 #define LM3533_LED_DELAY2_TMIN 1130496U
176 #define LM3533_LED_DELAY3_TMIN 10305536U 176 #define LM3533_LED_DELAY3_TMIN 10305536U
177 177
178 #define LM3533_LED_DELAY1_TMAX 999424U 178 #define LM3533_LED_DELAY1_TMAX 999424U
179 #define LM3533_LED_DELAY2_TMAX 9781248U 179 #define LM3533_LED_DELAY2_TMAX 9781248U
180 #define LM3533_LED_DELAY3_TMAX 76890112U 180 #define LM3533_LED_DELAY3_TMAX 76890112U
181 181
182 /* t_step = (t_max - t_min) / (v_max - v_min) */ 182 /* t_step = (t_max - t_min) / (v_max - v_min) */
183 #define LM3533_LED_DELAY1_TSTEP 16384 183 #define LM3533_LED_DELAY1_TSTEP 16384
184 #define LM3533_LED_DELAY2_TSTEP 131072 184 #define LM3533_LED_DELAY2_TSTEP 131072
185 #define LM3533_LED_DELAY3_TSTEP 524288 185 #define LM3533_LED_DELAY3_TSTEP 524288
186 186
187 /* Delay limits for hardware accelerated blinking (in ms). */ 187 /* Delay limits for hardware accelerated blinking (in ms). */
188 #define LM3533_LED_DELAY_ON_MAX \ 188 #define LM3533_LED_DELAY_ON_MAX \
189 ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000) 189 ((LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY2_TSTEP / 2) / 1000)
190 #define LM3533_LED_DELAY_OFF_MAX \ 190 #define LM3533_LED_DELAY_OFF_MAX \
191 ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000) 191 ((LM3533_LED_DELAY3_TMAX + LM3533_LED_DELAY3_TSTEP / 2) / 1000)
192 192
193 /* 193 /*
194 * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step 194 * Returns linear map of *t from [t_min,t_max] to [v_min,v_max] with a step
195 * size of t_step, where 195 * size of t_step, where
196 * 196 *
197 * t_step = (t_max - t_min) / (v_max - v_min) 197 * t_step = (t_max - t_min) / (v_max - v_min)
198 * 198 *
199 * and updates *t to reflect the mapped value. 199 * and updates *t to reflect the mapped value.
200 */ 200 */
201 static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step, 201 static u8 time_to_val(unsigned *t, unsigned t_min, unsigned t_step,
202 u8 v_min, u8 v_max) 202 u8 v_min, u8 v_max)
203 { 203 {
204 unsigned val; 204 unsigned val;
205 205
206 val = (*t + t_step / 2 - t_min) / t_step + v_min; 206 val = (*t + t_step / 2 - t_min) / t_step + v_min;
207 207
208 *t = t_step * (val - v_min) + t_min; 208 *t = t_step * (val - v_min) + t_min;
209 209
210 return (u8)val; 210 return (u8)val;
211 } 211 }
212 212
213 /* 213 /*
214 * Returns time code corresponding to *delay (in ms) and updates *delay to 214 * Returns time code corresponding to *delay (in ms) and updates *delay to
215 * reflect actual hardware delay. 215 * reflect actual hardware delay.
216 * 216 *
217 * Hardware supports 256 discrete delay times, divided into three groups with 217 * Hardware supports 256 discrete delay times, divided into three groups with
218 * the following ranges and step-sizes: 218 * the following ranges and step-sizes:
219 * 219 *
220 * [ 16, 999] [0x00, 0x3e] step 16 ms 220 * [ 16, 999] [0x00, 0x3e] step 16 ms
221 * [ 1130, 9781] [0x3d, 0x7f] step 131 ms 221 * [ 1130, 9781] [0x3d, 0x7f] step 131 ms
222 * [10306, 76890] [0x80, 0xff] step 524 ms 222 * [10306, 76890] [0x80, 0xff] step 524 ms
223 * 223 *
224 * Note that delay group 3 is only available for delay_off. 224 * Note that delay group 3 is only available for delay_off.
225 */ 225 */
226 static u8 lm3533_led_get_hw_delay(unsigned *delay) 226 static u8 lm3533_led_get_hw_delay(unsigned *delay)
227 { 227 {
228 unsigned t; 228 unsigned t;
229 u8 val; 229 u8 val;
230 230
231 t = *delay * 1000; 231 t = *delay * 1000;
232 232
233 if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) { 233 if (t >= (LM3533_LED_DELAY2_TMAX + LM3533_LED_DELAY3_TMIN) / 2) {
234 t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX); 234 t = clamp(t, LM3533_LED_DELAY3_TMIN, LM3533_LED_DELAY3_TMAX);
235 val = time_to_val(&t, LM3533_LED_DELAY3_TMIN, 235 val = time_to_val(&t, LM3533_LED_DELAY3_TMIN,
236 LM3533_LED_DELAY3_TSTEP, 236 LM3533_LED_DELAY3_TSTEP,
237 LM3533_LED_DELAY3_VMIN, 237 LM3533_LED_DELAY3_VMIN,
238 LM3533_LED_DELAY3_VMAX); 238 LM3533_LED_DELAY3_VMAX);
239 } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) { 239 } else if (t >= (LM3533_LED_DELAY1_TMAX + LM3533_LED_DELAY2_TMIN) / 2) {
240 t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX); 240 t = clamp(t, LM3533_LED_DELAY2_TMIN, LM3533_LED_DELAY2_TMAX);
241 val = time_to_val(&t, LM3533_LED_DELAY2_TMIN, 241 val = time_to_val(&t, LM3533_LED_DELAY2_TMIN,
242 LM3533_LED_DELAY2_TSTEP, 242 LM3533_LED_DELAY2_TSTEP,
243 LM3533_LED_DELAY2_VMIN, 243 LM3533_LED_DELAY2_VMIN,
244 LM3533_LED_DELAY2_VMAX); 244 LM3533_LED_DELAY2_VMAX);
245 } else { 245 } else {
246 t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX); 246 t = clamp(t, LM3533_LED_DELAY1_TMIN, LM3533_LED_DELAY1_TMAX);
247 val = time_to_val(&t, LM3533_LED_DELAY1_TMIN, 247 val = time_to_val(&t, LM3533_LED_DELAY1_TMIN,
248 LM3533_LED_DELAY1_TSTEP, 248 LM3533_LED_DELAY1_TSTEP,
249 LM3533_LED_DELAY1_VMIN, 249 LM3533_LED_DELAY1_VMIN,
250 LM3533_LED_DELAY1_VMAX); 250 LM3533_LED_DELAY1_VMAX);
251 } 251 }
252 252
253 *delay = (t + 500) / 1000; 253 *delay = (t + 500) / 1000;
254 254
255 return val; 255 return val;
256 } 256 }
257 257
258 /* 258 /*
259 * Set delay register base to *delay (in ms) and update *delay to reflect 259 * Set delay register base to *delay (in ms) and update *delay to reflect
260 * actual hardware delay used. 260 * actual hardware delay used.
261 */ 261 */
262 static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base, 262 static u8 lm3533_led_delay_set(struct lm3533_led *led, u8 base,
263 unsigned long *delay) 263 unsigned long *delay)
264 { 264 {
265 unsigned t; 265 unsigned t;
266 u8 val; 266 u8 val;
267 u8 reg; 267 u8 reg;
268 int ret; 268 int ret;
269 269
270 t = (unsigned)*delay; 270 t = (unsigned)*delay;
271 271
272 /* Delay group 3 is only available for low time (delay off). */ 272 /* Delay group 3 is only available for low time (delay off). */
273 if (base != LM3533_REG_PATTERN_LOW_TIME_BASE) 273 if (base != LM3533_REG_PATTERN_LOW_TIME_BASE)
274 t = min(t, LM3533_LED_DELAY2_TMAX / 1000); 274 t = min(t, LM3533_LED_DELAY2_TMAX / 1000);
275 275
276 val = lm3533_led_get_hw_delay(&t); 276 val = lm3533_led_get_hw_delay(&t);
277 277
278 dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__, 278 dev_dbg(led->cdev.dev, "%s - %lu: %u (0x%02x)\n", __func__,
279 *delay, t, val); 279 *delay, t, val);
280 reg = lm3533_led_get_pattern_reg(led, base); 280 reg = lm3533_led_get_pattern_reg(led, base);
281 ret = lm3533_write(led->lm3533, reg, val); 281 ret = lm3533_write(led->lm3533, reg, val);
282 if (ret) 282 if (ret)
283 dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg); 283 dev_err(led->cdev.dev, "failed to set delay (%02x)\n", reg);
284 284
285 *delay = t; 285 *delay = t;
286 286
287 return ret; 287 return ret;
288 } 288 }
289 289
290 static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t) 290 static int lm3533_led_delay_on_set(struct lm3533_led *led, unsigned long *t)
291 { 291 {
292 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t); 292 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_HIGH_TIME_BASE, t);
293 } 293 }
294 294
295 static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t) 295 static int lm3533_led_delay_off_set(struct lm3533_led *led, unsigned long *t)
296 { 296 {
297 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t); 297 return lm3533_led_delay_set(led, LM3533_REG_PATTERN_LOW_TIME_BASE, t);
298 } 298 }
299 299
300 static int lm3533_led_blink_set(struct led_classdev *cdev, 300 static int lm3533_led_blink_set(struct led_classdev *cdev,
301 unsigned long *delay_on, 301 unsigned long *delay_on,
302 unsigned long *delay_off) 302 unsigned long *delay_off)
303 { 303 {
304 struct lm3533_led *led = to_lm3533_led(cdev); 304 struct lm3533_led *led = to_lm3533_led(cdev);
305 int ret; 305 int ret;
306 306
307 dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__, 307 dev_dbg(led->cdev.dev, "%s - on = %lu, off = %lu\n", __func__,
308 *delay_on, *delay_off); 308 *delay_on, *delay_off);
309 309
310 if (*delay_on > LM3533_LED_DELAY_ON_MAX || 310 if (*delay_on > LM3533_LED_DELAY_ON_MAX ||
311 *delay_off > LM3533_LED_DELAY_OFF_MAX) 311 *delay_off > LM3533_LED_DELAY_OFF_MAX)
312 return -EINVAL; 312 return -EINVAL;
313 313
314 if (*delay_on == 0 && *delay_off == 0) { 314 if (*delay_on == 0 && *delay_off == 0) {
315 *delay_on = 500; 315 *delay_on = 500;
316 *delay_off = 500; 316 *delay_off = 500;
317 } 317 }
318 318
319 ret = lm3533_led_delay_on_set(led, delay_on); 319 ret = lm3533_led_delay_on_set(led, delay_on);
320 if (ret) 320 if (ret)
321 return ret; 321 return ret;
322 322
323 ret = lm3533_led_delay_off_set(led, delay_off); 323 ret = lm3533_led_delay_off_set(led, delay_off);
324 if (ret) 324 if (ret)
325 return ret; 325 return ret;
326 326
327 return lm3533_led_pattern_enable(led, 1); 327 return lm3533_led_pattern_enable(led, 1);
328 } 328 }
329 329
330 static ssize_t show_id(struct device *dev, 330 static ssize_t show_id(struct device *dev,
331 struct device_attribute *attr, char *buf) 331 struct device_attribute *attr, char *buf)
332 { 332 {
333 struct led_classdev *led_cdev = dev_get_drvdata(dev); 333 struct led_classdev *led_cdev = dev_get_drvdata(dev);
334 struct lm3533_led *led = to_lm3533_led(led_cdev); 334 struct lm3533_led *led = to_lm3533_led(led_cdev);
335 335
336 return scnprintf(buf, PAGE_SIZE, "%d\n", led->id); 336 return scnprintf(buf, PAGE_SIZE, "%d\n", led->id);
337 } 337 }
338 338
339 /* 339 /*
340 * Pattern generator rise/fall times: 340 * Pattern generator rise/fall times:
341 * 341 *
342 * 0 - 2048 us (default) 342 * 0 - 2048 us (default)
343 * 1 - 262 ms 343 * 1 - 262 ms
344 * 2 - 524 ms 344 * 2 - 524 ms
345 * 3 - 1.049 s 345 * 3 - 1.049 s
346 * 4 - 2.097 s 346 * 4 - 2.097 s
347 * 5 - 4.194 s 347 * 5 - 4.194 s
348 * 6 - 8.389 s 348 * 6 - 8.389 s
349 * 7 - 16.78 s 349 * 7 - 16.78 s
350 */ 350 */
351 static ssize_t show_risefalltime(struct device *dev, 351 static ssize_t show_risefalltime(struct device *dev,
352 struct device_attribute *attr, 352 struct device_attribute *attr,
353 char *buf, u8 base) 353 char *buf, u8 base)
354 { 354 {
355 struct led_classdev *led_cdev = dev_get_drvdata(dev); 355 struct led_classdev *led_cdev = dev_get_drvdata(dev);
356 struct lm3533_led *led = to_lm3533_led(led_cdev); 356 struct lm3533_led *led = to_lm3533_led(led_cdev);
357 ssize_t ret; 357 ssize_t ret;
358 u8 reg; 358 u8 reg;
359 u8 val; 359 u8 val;
360 360
361 reg = lm3533_led_get_pattern_reg(led, base); 361 reg = lm3533_led_get_pattern_reg(led, base);
362 ret = lm3533_read(led->lm3533, reg, &val); 362 ret = lm3533_read(led->lm3533, reg, &val);
363 if (ret) 363 if (ret)
364 return ret; 364 return ret;
365 365
366 return scnprintf(buf, PAGE_SIZE, "%x\n", val); 366 return scnprintf(buf, PAGE_SIZE, "%x\n", val);
367 } 367 }
368 368
369 static ssize_t show_risetime(struct device *dev, 369 static ssize_t show_risetime(struct device *dev,
370 struct device_attribute *attr, char *buf) 370 struct device_attribute *attr, char *buf)
371 { 371 {
372 return show_risefalltime(dev, attr, buf, 372 return show_risefalltime(dev, attr, buf,
373 LM3533_REG_PATTERN_RISETIME_BASE); 373 LM3533_REG_PATTERN_RISETIME_BASE);
374 } 374 }
375 375
376 static ssize_t show_falltime(struct device *dev, 376 static ssize_t show_falltime(struct device *dev,
377 struct device_attribute *attr, char *buf) 377 struct device_attribute *attr, char *buf)
378 { 378 {
379 return show_risefalltime(dev, attr, buf, 379 return show_risefalltime(dev, attr, buf,
380 LM3533_REG_PATTERN_FALLTIME_BASE); 380 LM3533_REG_PATTERN_FALLTIME_BASE);
381 } 381 }
382 382
383 static ssize_t store_risefalltime(struct device *dev, 383 static ssize_t store_risefalltime(struct device *dev,
384 struct device_attribute *attr, 384 struct device_attribute *attr,
385 const char *buf, size_t len, u8 base) 385 const char *buf, size_t len, u8 base)
386 { 386 {
387 struct led_classdev *led_cdev = dev_get_drvdata(dev); 387 struct led_classdev *led_cdev = dev_get_drvdata(dev);
388 struct lm3533_led *led = to_lm3533_led(led_cdev); 388 struct lm3533_led *led = to_lm3533_led(led_cdev);
389 u8 val; 389 u8 val;
390 u8 reg; 390 u8 reg;
391 int ret; 391 int ret;
392 392
393 if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX) 393 if (kstrtou8(buf, 0, &val) || val > LM3533_RISEFALLTIME_MAX)
394 return -EINVAL; 394 return -EINVAL;
395 395
396 reg = lm3533_led_get_pattern_reg(led, base); 396 reg = lm3533_led_get_pattern_reg(led, base);
397 ret = lm3533_write(led->lm3533, reg, val); 397 ret = lm3533_write(led->lm3533, reg, val);
398 if (ret) 398 if (ret)
399 return ret; 399 return ret;
400 400
401 return len; 401 return len;
402 } 402 }
403 403
404 static ssize_t store_risetime(struct device *dev, 404 static ssize_t store_risetime(struct device *dev,
405 struct device_attribute *attr, 405 struct device_attribute *attr,
406 const char *buf, size_t len) 406 const char *buf, size_t len)
407 { 407 {
408 return store_risefalltime(dev, attr, buf, len, 408 return store_risefalltime(dev, attr, buf, len,
409 LM3533_REG_PATTERN_RISETIME_BASE); 409 LM3533_REG_PATTERN_RISETIME_BASE);
410 } 410 }
411 411
412 static ssize_t store_falltime(struct device *dev, 412 static ssize_t store_falltime(struct device *dev,
413 struct device_attribute *attr, 413 struct device_attribute *attr,
414 const char *buf, size_t len) 414 const char *buf, size_t len)
415 { 415 {
416 return store_risefalltime(dev, attr, buf, len, 416 return store_risefalltime(dev, attr, buf, len,
417 LM3533_REG_PATTERN_FALLTIME_BASE); 417 LM3533_REG_PATTERN_FALLTIME_BASE);
418 } 418 }
419 419
420 static ssize_t show_als_channel(struct device *dev, 420 static ssize_t show_als_channel(struct device *dev,
421 struct device_attribute *attr, char *buf) 421 struct device_attribute *attr, char *buf)
422 { 422 {
423 struct led_classdev *led_cdev = dev_get_drvdata(dev); 423 struct led_classdev *led_cdev = dev_get_drvdata(dev);
424 struct lm3533_led *led = to_lm3533_led(led_cdev); 424 struct lm3533_led *led = to_lm3533_led(led_cdev);
425 unsigned channel; 425 unsigned channel;
426 u8 reg; 426 u8 reg;
427 u8 val; 427 u8 val;
428 int ret; 428 int ret;
429 429
430 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 430 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
431 ret = lm3533_read(led->lm3533, reg, &val); 431 ret = lm3533_read(led->lm3533, reg, &val);
432 if (ret) 432 if (ret)
433 return ret; 433 return ret;
434 434
435 channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1; 435 channel = (val & LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK) + 1;
436 436
437 return scnprintf(buf, PAGE_SIZE, "%u\n", channel); 437 return scnprintf(buf, PAGE_SIZE, "%u\n", channel);
438 } 438 }
439 439
440 static ssize_t store_als_channel(struct device *dev, 440 static ssize_t store_als_channel(struct device *dev,
441 struct device_attribute *attr, 441 struct device_attribute *attr,
442 const char *buf, size_t len) 442 const char *buf, size_t len)
443 { 443 {
444 struct led_classdev *led_cdev = dev_get_drvdata(dev); 444 struct led_classdev *led_cdev = dev_get_drvdata(dev);
445 struct lm3533_led *led = to_lm3533_led(led_cdev); 445 struct lm3533_led *led = to_lm3533_led(led_cdev);
446 unsigned channel; 446 unsigned channel;
447 u8 reg; 447 u8 reg;
448 u8 val; 448 u8 val;
449 u8 mask; 449 u8 mask;
450 int ret; 450 int ret;
451 451
452 if (kstrtouint(buf, 0, &channel)) 452 if (kstrtouint(buf, 0, &channel))
453 return -EINVAL; 453 return -EINVAL;
454 454
455 if (channel < LM3533_ALS_CHANNEL_LV_MIN || 455 if (channel < LM3533_ALS_CHANNEL_LV_MIN ||
456 channel > LM3533_ALS_CHANNEL_LV_MAX) 456 channel > LM3533_ALS_CHANNEL_LV_MAX)
457 return -EINVAL; 457 return -EINVAL;
458 458
459 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 459 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
460 mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK; 460 mask = LM3533_REG_CTRLBANK_BCONF_ALS_CHANNEL_MASK;
461 val = channel - 1; 461 val = channel - 1;
462 462
463 ret = lm3533_update(led->lm3533, reg, val, mask); 463 ret = lm3533_update(led->lm3533, reg, val, mask);
464 if (ret) 464 if (ret)
465 return ret; 465 return ret;
466 466
467 return len; 467 return len;
468 } 468 }
469 469
470 static ssize_t show_als_en(struct device *dev, 470 static ssize_t show_als_en(struct device *dev,
471 struct device_attribute *attr, char *buf) 471 struct device_attribute *attr, char *buf)
472 { 472 {
473 struct led_classdev *led_cdev = dev_get_drvdata(dev); 473 struct led_classdev *led_cdev = dev_get_drvdata(dev);
474 struct lm3533_led *led = to_lm3533_led(led_cdev); 474 struct lm3533_led *led = to_lm3533_led(led_cdev);
475 bool enable; 475 bool enable;
476 u8 reg; 476 u8 reg;
477 u8 val; 477 u8 val;
478 int ret; 478 int ret;
479 479
480 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 480 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
481 ret = lm3533_read(led->lm3533, reg, &val); 481 ret = lm3533_read(led->lm3533, reg, &val);
482 if (ret) 482 if (ret)
483 return ret; 483 return ret;
484 484
485 enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK; 485 enable = val & LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
486 486
487 return scnprintf(buf, PAGE_SIZE, "%d\n", enable); 487 return scnprintf(buf, PAGE_SIZE, "%d\n", enable);
488 } 488 }
489 489
490 static ssize_t store_als_en(struct device *dev, 490 static ssize_t store_als_en(struct device *dev,
491 struct device_attribute *attr, 491 struct device_attribute *attr,
492 const char *buf, size_t len) 492 const char *buf, size_t len)
493 { 493 {
494 struct led_classdev *led_cdev = dev_get_drvdata(dev); 494 struct led_classdev *led_cdev = dev_get_drvdata(dev);
495 struct lm3533_led *led = to_lm3533_led(led_cdev); 495 struct lm3533_led *led = to_lm3533_led(led_cdev);
496 unsigned enable; 496 unsigned enable;
497 u8 reg; 497 u8 reg;
498 u8 mask; 498 u8 mask;
499 u8 val; 499 u8 val;
500 int ret; 500 int ret;
501 501
502 if (kstrtouint(buf, 0, &enable)) 502 if (kstrtouint(buf, 0, &enable))
503 return -EINVAL; 503 return -EINVAL;
504 504
505 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 505 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
506 mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK; 506 mask = LM3533_REG_CTRLBANK_BCONF_ALS_EN_MASK;
507 507
508 if (enable) 508 if (enable)
509 val = mask; 509 val = mask;
510 else 510 else
511 val = 0; 511 val = 0;
512 512
513 ret = lm3533_update(led->lm3533, reg, val, mask); 513 ret = lm3533_update(led->lm3533, reg, val, mask);
514 if (ret) 514 if (ret)
515 return ret; 515 return ret;
516 516
517 return len; 517 return len;
518 } 518 }
519 519
520 static ssize_t show_linear(struct device *dev, 520 static ssize_t show_linear(struct device *dev,
521 struct device_attribute *attr, char *buf) 521 struct device_attribute *attr, char *buf)
522 { 522 {
523 struct led_classdev *led_cdev = dev_get_drvdata(dev); 523 struct led_classdev *led_cdev = dev_get_drvdata(dev);
524 struct lm3533_led *led = to_lm3533_led(led_cdev); 524 struct lm3533_led *led = to_lm3533_led(led_cdev);
525 u8 reg; 525 u8 reg;
526 u8 val; 526 u8 val;
527 int linear; 527 int linear;
528 int ret; 528 int ret;
529 529
530 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 530 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
531 ret = lm3533_read(led->lm3533, reg, &val); 531 ret = lm3533_read(led->lm3533, reg, &val);
532 if (ret) 532 if (ret)
533 return ret; 533 return ret;
534 534
535 if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK) 535 if (val & LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK)
536 linear = 1; 536 linear = 1;
537 else 537 else
538 linear = 0; 538 linear = 0;
539 539
540 return scnprintf(buf, PAGE_SIZE, "%x\n", linear); 540 return scnprintf(buf, PAGE_SIZE, "%x\n", linear);
541 } 541 }
542 542
543 static ssize_t store_linear(struct device *dev, 543 static ssize_t store_linear(struct device *dev,
544 struct device_attribute *attr, 544 struct device_attribute *attr,
545 const char *buf, size_t len) 545 const char *buf, size_t len)
546 { 546 {
547 struct led_classdev *led_cdev = dev_get_drvdata(dev); 547 struct led_classdev *led_cdev = dev_get_drvdata(dev);
548 struct lm3533_led *led = to_lm3533_led(led_cdev); 548 struct lm3533_led *led = to_lm3533_led(led_cdev);
549 unsigned long linear; 549 unsigned long linear;
550 u8 reg; 550 u8 reg;
551 u8 mask; 551 u8 mask;
552 u8 val; 552 u8 val;
553 int ret; 553 int ret;
554 554
555 if (kstrtoul(buf, 0, &linear)) 555 if (kstrtoul(buf, 0, &linear))
556 return -EINVAL; 556 return -EINVAL;
557 557
558 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE); 558 reg = lm3533_led_get_lv_reg(led, LM3533_REG_CTRLBANK_BCONF_BASE);
559 mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK; 559 mask = LM3533_REG_CTRLBANK_BCONF_MAPPING_MASK;
560 560
561 if (linear) 561 if (linear)
562 val = mask; 562 val = mask;
563 else 563 else
564 val = 0; 564 val = 0;
565 565
566 ret = lm3533_update(led->lm3533, reg, val, mask); 566 ret = lm3533_update(led->lm3533, reg, val, mask);
567 if (ret) 567 if (ret)
568 return ret; 568 return ret;
569 569
570 return len; 570 return len;
571 } 571 }
572 572
573 static ssize_t show_pwm(struct device *dev, 573 static ssize_t show_pwm(struct device *dev,
574 struct device_attribute *attr, 574 struct device_attribute *attr,
575 char *buf) 575 char *buf)
576 { 576 {
577 struct led_classdev *led_cdev = dev_get_drvdata(dev); 577 struct led_classdev *led_cdev = dev_get_drvdata(dev);
578 struct lm3533_led *led = to_lm3533_led(led_cdev); 578 struct lm3533_led *led = to_lm3533_led(led_cdev);
579 u8 val; 579 u8 val;
580 int ret; 580 int ret;
581 581
582 ret = lm3533_ctrlbank_get_pwm(&led->cb, &val); 582 ret = lm3533_ctrlbank_get_pwm(&led->cb, &val);
583 if (ret) 583 if (ret)
584 return ret; 584 return ret;
585 585
586 return scnprintf(buf, PAGE_SIZE, "%u\n", val); 586 return scnprintf(buf, PAGE_SIZE, "%u\n", val);
587 } 587 }
588 588
589 static ssize_t store_pwm(struct device *dev, 589 static ssize_t store_pwm(struct device *dev,
590 struct device_attribute *attr, 590 struct device_attribute *attr,
591 const char *buf, size_t len) 591 const char *buf, size_t len)
592 { 592 {
593 struct led_classdev *led_cdev = dev_get_drvdata(dev); 593 struct led_classdev *led_cdev = dev_get_drvdata(dev);
594 struct lm3533_led *led = to_lm3533_led(led_cdev); 594 struct lm3533_led *led = to_lm3533_led(led_cdev);
595 u8 val; 595 u8 val;
596 int ret; 596 int ret;
597 597
598 if (kstrtou8(buf, 0, &val)) 598 if (kstrtou8(buf, 0, &val))
599 return -EINVAL; 599 return -EINVAL;
600 600
601 ret = lm3533_ctrlbank_set_pwm(&led->cb, val); 601 ret = lm3533_ctrlbank_set_pwm(&led->cb, val);
602 if (ret) 602 if (ret)
603 return ret; 603 return ret;
604 604
605 return len; 605 return len;
606 } 606 }
607 607
608 static LM3533_ATTR_RW(als_channel); 608 static LM3533_ATTR_RW(als_channel);
609 static LM3533_ATTR_RW(als_en); 609 static LM3533_ATTR_RW(als_en);
610 static LM3533_ATTR_RW(falltime); 610 static LM3533_ATTR_RW(falltime);
611 static LM3533_ATTR_RO(id); 611 static LM3533_ATTR_RO(id);
612 static LM3533_ATTR_RW(linear); 612 static LM3533_ATTR_RW(linear);
613 static LM3533_ATTR_RW(pwm); 613 static LM3533_ATTR_RW(pwm);
614 static LM3533_ATTR_RW(risetime); 614 static LM3533_ATTR_RW(risetime);
615 615
616 static struct attribute *lm3533_led_attributes[] = { 616 static struct attribute *lm3533_led_attributes[] = {
617 &dev_attr_als_channel.attr, 617 &dev_attr_als_channel.attr,
618 &dev_attr_als_en.attr, 618 &dev_attr_als_en.attr,
619 &dev_attr_falltime.attr, 619 &dev_attr_falltime.attr,
620 &dev_attr_id.attr, 620 &dev_attr_id.attr,
621 &dev_attr_linear.attr, 621 &dev_attr_linear.attr,
622 &dev_attr_pwm.attr, 622 &dev_attr_pwm.attr,
623 &dev_attr_risetime.attr, 623 &dev_attr_risetime.attr,
624 NULL, 624 NULL,
625 }; 625 };
626 626
627 static umode_t lm3533_led_attr_is_visible(struct kobject *kobj, 627 static umode_t lm3533_led_attr_is_visible(struct kobject *kobj,
628 struct attribute *attr, int n) 628 struct attribute *attr, int n)
629 { 629 {
630 struct device *dev = container_of(kobj, struct device, kobj); 630 struct device *dev = container_of(kobj, struct device, kobj);
631 struct led_classdev *led_cdev = dev_get_drvdata(dev); 631 struct led_classdev *led_cdev = dev_get_drvdata(dev);
632 struct lm3533_led *led = to_lm3533_led(led_cdev); 632 struct lm3533_led *led = to_lm3533_led(led_cdev);
633 umode_t mode = attr->mode; 633 umode_t mode = attr->mode;
634 634
635 if (attr == &dev_attr_als_channel.attr || 635 if (attr == &dev_attr_als_channel.attr ||
636 attr == &dev_attr_als_en.attr) { 636 attr == &dev_attr_als_en.attr) {
637 if (!led->lm3533->have_als) 637 if (!led->lm3533->have_als)
638 mode = 0; 638 mode = 0;
639 } 639 }
640 640
641 return mode; 641 return mode;
642 }; 642 };
643 643
644 static struct attribute_group lm3533_led_attribute_group = { 644 static struct attribute_group lm3533_led_attribute_group = {
645 .is_visible = lm3533_led_attr_is_visible, 645 .is_visible = lm3533_led_attr_is_visible,
646 .attrs = lm3533_led_attributes 646 .attrs = lm3533_led_attributes
647 }; 647 };
648 648
649 static int lm3533_led_setup(struct lm3533_led *led, 649 static int lm3533_led_setup(struct lm3533_led *led,
650 struct lm3533_led_platform_data *pdata) 650 struct lm3533_led_platform_data *pdata)
651 { 651 {
652 int ret; 652 int ret;
653 653
654 ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current); 654 ret = lm3533_ctrlbank_set_max_current(&led->cb, pdata->max_current);
655 if (ret) 655 if (ret)
656 return ret; 656 return ret;
657 657
658 return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm); 658 return lm3533_ctrlbank_set_pwm(&led->cb, pdata->pwm);
659 } 659 }
660 660
661 static int lm3533_led_probe(struct platform_device *pdev) 661 static int lm3533_led_probe(struct platform_device *pdev)
662 { 662 {
663 struct lm3533 *lm3533; 663 struct lm3533 *lm3533;
664 struct lm3533_led_platform_data *pdata; 664 struct lm3533_led_platform_data *pdata;
665 struct lm3533_led *led; 665 struct lm3533_led *led;
666 int ret; 666 int ret;
667 667
668 dev_dbg(&pdev->dev, "%s\n", __func__); 668 dev_dbg(&pdev->dev, "%s\n", __func__);
669 669
670 lm3533 = dev_get_drvdata(pdev->dev.parent); 670 lm3533 = dev_get_drvdata(pdev->dev.parent);
671 if (!lm3533) 671 if (!lm3533)
672 return -EINVAL; 672 return -EINVAL;
673 673
674 pdata = pdev->dev.platform_data; 674 pdata = dev_get_platdata(&pdev->dev);
675 if (!pdata) { 675 if (!pdata) {
676 dev_err(&pdev->dev, "no platform data\n"); 676 dev_err(&pdev->dev, "no platform data\n");
677 return -EINVAL; 677 return -EINVAL;
678 } 678 }
679 679
680 if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) { 680 if (pdev->id < 0 || pdev->id >= LM3533_LVCTRLBANK_COUNT) {
681 dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id); 681 dev_err(&pdev->dev, "illegal LED id %d\n", pdev->id);
682 return -EINVAL; 682 return -EINVAL;
683 } 683 }
684 684
685 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); 685 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
686 if (!led) 686 if (!led)
687 return -ENOMEM; 687 return -ENOMEM;
688 688
689 led->lm3533 = lm3533; 689 led->lm3533 = lm3533;
690 led->cdev.name = pdata->name; 690 led->cdev.name = pdata->name;
691 led->cdev.default_trigger = pdata->default_trigger; 691 led->cdev.default_trigger = pdata->default_trigger;
692 led->cdev.brightness_set = lm3533_led_set; 692 led->cdev.brightness_set = lm3533_led_set;
693 led->cdev.brightness_get = lm3533_led_get; 693 led->cdev.brightness_get = lm3533_led_get;
694 led->cdev.blink_set = lm3533_led_blink_set; 694 led->cdev.blink_set = lm3533_led_blink_set;
695 led->cdev.brightness = LED_OFF; 695 led->cdev.brightness = LED_OFF;
696 led->id = pdev->id; 696 led->id = pdev->id;
697 697
698 mutex_init(&led->mutex); 698 mutex_init(&led->mutex);
699 INIT_WORK(&led->work, lm3533_led_work); 699 INIT_WORK(&led->work, lm3533_led_work);
700 700
701 /* The class framework makes a callback to get brightness during 701 /* The class framework makes a callback to get brightness during
702 * registration so use parent device (for error reporting) until 702 * registration so use parent device (for error reporting) until
703 * registered. 703 * registered.
704 */ 704 */
705 led->cb.lm3533 = lm3533; 705 led->cb.lm3533 = lm3533;
706 led->cb.id = lm3533_led_get_ctrlbank_id(led); 706 led->cb.id = lm3533_led_get_ctrlbank_id(led);
707 led->cb.dev = lm3533->dev; 707 led->cb.dev = lm3533->dev;
708 708
709 platform_set_drvdata(pdev, led); 709 platform_set_drvdata(pdev, led);
710 710
711 ret = led_classdev_register(pdev->dev.parent, &led->cdev); 711 ret = led_classdev_register(pdev->dev.parent, &led->cdev);
712 if (ret) { 712 if (ret) {
713 dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id); 713 dev_err(&pdev->dev, "failed to register LED %d\n", pdev->id);
714 return ret; 714 return ret;
715 } 715 }
716 716
717 led->cb.dev = led->cdev.dev; 717 led->cb.dev = led->cdev.dev;
718 718
719 ret = sysfs_create_group(&led->cdev.dev->kobj, 719 ret = sysfs_create_group(&led->cdev.dev->kobj,
720 &lm3533_led_attribute_group); 720 &lm3533_led_attribute_group);
721 if (ret < 0) { 721 if (ret < 0) {
722 dev_err(&pdev->dev, "failed to create sysfs attributes\n"); 722 dev_err(&pdev->dev, "failed to create sysfs attributes\n");
723 goto err_unregister; 723 goto err_unregister;
724 } 724 }
725 725
726 ret = lm3533_led_setup(led, pdata); 726 ret = lm3533_led_setup(led, pdata);
727 if (ret) 727 if (ret)
728 goto err_sysfs_remove; 728 goto err_sysfs_remove;
729 729
730 ret = lm3533_ctrlbank_enable(&led->cb); 730 ret = lm3533_ctrlbank_enable(&led->cb);
731 if (ret) 731 if (ret)
732 goto err_sysfs_remove; 732 goto err_sysfs_remove;
733 733
734 return 0; 734 return 0;
735 735
736 err_sysfs_remove: 736 err_sysfs_remove:
737 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group); 737 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
738 err_unregister: 738 err_unregister:
739 led_classdev_unregister(&led->cdev); 739 led_classdev_unregister(&led->cdev);
740 flush_work(&led->work); 740 flush_work(&led->work);
741 741
742 return ret; 742 return ret;
743 } 743 }
744 744
745 static int lm3533_led_remove(struct platform_device *pdev) 745 static int lm3533_led_remove(struct platform_device *pdev)
746 { 746 {
747 struct lm3533_led *led = platform_get_drvdata(pdev); 747 struct lm3533_led *led = platform_get_drvdata(pdev);
748 748
749 dev_dbg(&pdev->dev, "%s\n", __func__); 749 dev_dbg(&pdev->dev, "%s\n", __func__);
750 750
751 lm3533_ctrlbank_disable(&led->cb); 751 lm3533_ctrlbank_disable(&led->cb);
752 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group); 752 sysfs_remove_group(&led->cdev.dev->kobj, &lm3533_led_attribute_group);
753 led_classdev_unregister(&led->cdev); 753 led_classdev_unregister(&led->cdev);
754 flush_work(&led->work); 754 flush_work(&led->work);
755 755
756 return 0; 756 return 0;
757 } 757 }
758 758
759 static void lm3533_led_shutdown(struct platform_device *pdev) 759 static void lm3533_led_shutdown(struct platform_device *pdev)
760 { 760 {
761 761
762 struct lm3533_led *led = platform_get_drvdata(pdev); 762 struct lm3533_led *led = platform_get_drvdata(pdev);
763 763
764 dev_dbg(&pdev->dev, "%s\n", __func__); 764 dev_dbg(&pdev->dev, "%s\n", __func__);
765 765
766 lm3533_ctrlbank_disable(&led->cb); 766 lm3533_ctrlbank_disable(&led->cb);
767 lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */ 767 lm3533_led_set(&led->cdev, LED_OFF); /* disable blink */
768 flush_work(&led->work); 768 flush_work(&led->work);
769 } 769 }
770 770
771 static struct platform_driver lm3533_led_driver = { 771 static struct platform_driver lm3533_led_driver = {
772 .driver = { 772 .driver = {
773 .name = "lm3533-leds", 773 .name = "lm3533-leds",
774 .owner = THIS_MODULE, 774 .owner = THIS_MODULE,
775 }, 775 },
776 .probe = lm3533_led_probe, 776 .probe = lm3533_led_probe,
777 .remove = lm3533_led_remove, 777 .remove = lm3533_led_remove,
778 .shutdown = lm3533_led_shutdown, 778 .shutdown = lm3533_led_shutdown,
779 }; 779 };
780 module_platform_driver(lm3533_led_driver); 780 module_platform_driver(lm3533_led_driver);
781 781
782 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>"); 782 MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
783 MODULE_DESCRIPTION("LM3533 LED driver"); 783 MODULE_DESCRIPTION("LM3533 LED driver");
784 MODULE_LICENSE("GPL"); 784 MODULE_LICENSE("GPL");
785 MODULE_ALIAS("platform:lm3533-leds"); 785 MODULE_ALIAS("platform:lm3533-leds");
786 786
drivers/leds/leds-lm355x.c
1 /* 1 /*
2 * Simple driver for Texas Instruments LM355x LED Flash driver chip 2 * Simple driver for Texas Instruments LM355x LED Flash driver chip
3 * Copyright (C) 2012 Texas Instruments 3 * Copyright (C) 2012 Texas Instruments
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 */ 8 */
9 9
10 #include <linux/module.h> 10 #include <linux/module.h>
11 #include <linux/delay.h> 11 #include <linux/delay.h>
12 #include <linux/i2c.h> 12 #include <linux/i2c.h>
13 #include <linux/gpio.h> 13 #include <linux/gpio.h>
14 #include <linux/leds.h> 14 #include <linux/leds.h>
15 #include <linux/slab.h> 15 #include <linux/slab.h>
16 #include <linux/platform_device.h> 16 #include <linux/platform_device.h>
17 #include <linux/fs.h> 17 #include <linux/fs.h>
18 #include <linux/regmap.h> 18 #include <linux/regmap.h>
19 #include <linux/workqueue.h> 19 #include <linux/workqueue.h>
20 #include <linux/platform_data/leds-lm355x.h> 20 #include <linux/platform_data/leds-lm355x.h>
21 21
22 enum lm355x_type { 22 enum lm355x_type {
23 CHIP_LM3554 = 0, 23 CHIP_LM3554 = 0,
24 CHIP_LM3556, 24 CHIP_LM3556,
25 }; 25 };
26 26
27 enum lm355x_regs { 27 enum lm355x_regs {
28 REG_FLAG = 0, 28 REG_FLAG = 0,
29 REG_TORCH_CFG, 29 REG_TORCH_CFG,
30 REG_TORCH_CTRL, 30 REG_TORCH_CTRL,
31 REG_STROBE_CFG, 31 REG_STROBE_CFG,
32 REG_FLASH_CTRL, 32 REG_FLASH_CTRL,
33 REG_INDI_CFG, 33 REG_INDI_CFG,
34 REG_INDI_CTRL, 34 REG_INDI_CTRL,
35 REG_OPMODE, 35 REG_OPMODE,
36 REG_MAX, 36 REG_MAX,
37 }; 37 };
38 38
39 /* operation mode */ 39 /* operation mode */
40 enum lm355x_mode { 40 enum lm355x_mode {
41 MODE_SHDN = 0, 41 MODE_SHDN = 0,
42 MODE_INDIC, 42 MODE_INDIC,
43 MODE_TORCH, 43 MODE_TORCH,
44 MODE_FLASH 44 MODE_FLASH
45 }; 45 };
46 46
47 /* register map info. */ 47 /* register map info. */
48 struct lm355x_reg_data { 48 struct lm355x_reg_data {
49 u8 regno; 49 u8 regno;
50 u8 mask; 50 u8 mask;
51 u8 shift; 51 u8 shift;
52 }; 52 };
53 53
54 struct lm355x_chip_data { 54 struct lm355x_chip_data {
55 struct device *dev; 55 struct device *dev;
56 enum lm355x_type type; 56 enum lm355x_type type;
57 57
58 struct led_classdev cdev_flash; 58 struct led_classdev cdev_flash;
59 struct led_classdev cdev_torch; 59 struct led_classdev cdev_torch;
60 struct led_classdev cdev_indicator; 60 struct led_classdev cdev_indicator;
61 61
62 struct work_struct work_flash; 62 struct work_struct work_flash;
63 struct work_struct work_torch; 63 struct work_struct work_torch;
64 struct work_struct work_indicator; 64 struct work_struct work_indicator;
65 65
66 u8 br_flash; 66 u8 br_flash;
67 u8 br_torch; 67 u8 br_torch;
68 u8 br_indicator; 68 u8 br_indicator;
69 69
70 struct lm355x_platform_data *pdata; 70 struct lm355x_platform_data *pdata;
71 struct regmap *regmap; 71 struct regmap *regmap;
72 struct mutex lock; 72 struct mutex lock;
73 73
74 unsigned int last_flag; 74 unsigned int last_flag;
75 struct lm355x_reg_data *regs; 75 struct lm355x_reg_data *regs;
76 }; 76 };
77 77
78 /* specific indicator function for lm3556 */ 78 /* specific indicator function for lm3556 */
79 enum lm3556_indic_pulse_time { 79 enum lm3556_indic_pulse_time {
80 PULSE_TIME_0_MS = 0, 80 PULSE_TIME_0_MS = 0,
81 PULSE_TIME_32_MS, 81 PULSE_TIME_32_MS,
82 PULSE_TIME_64_MS, 82 PULSE_TIME_64_MS,
83 PULSE_TIME_92_MS, 83 PULSE_TIME_92_MS,
84 PULSE_TIME_128_MS, 84 PULSE_TIME_128_MS,
85 PULSE_TIME_160_MS, 85 PULSE_TIME_160_MS,
86 PULSE_TIME_196_MS, 86 PULSE_TIME_196_MS,
87 PULSE_TIME_224_MS, 87 PULSE_TIME_224_MS,
88 PULSE_TIME_256_MS, 88 PULSE_TIME_256_MS,
89 PULSE_TIME_288_MS, 89 PULSE_TIME_288_MS,
90 PULSE_TIME_320_MS, 90 PULSE_TIME_320_MS,
91 PULSE_TIME_352_MS, 91 PULSE_TIME_352_MS,
92 PULSE_TIME_384_MS, 92 PULSE_TIME_384_MS,
93 PULSE_TIME_416_MS, 93 PULSE_TIME_416_MS,
94 PULSE_TIME_448_MS, 94 PULSE_TIME_448_MS,
95 PULSE_TIME_480_MS, 95 PULSE_TIME_480_MS,
96 }; 96 };
97 97
98 enum lm3556_indic_n_blank { 98 enum lm3556_indic_n_blank {
99 INDIC_N_BLANK_0 = 0, 99 INDIC_N_BLANK_0 = 0,
100 INDIC_N_BLANK_1, 100 INDIC_N_BLANK_1,
101 INDIC_N_BLANK_2, 101 INDIC_N_BLANK_2,
102 INDIC_N_BLANK_3, 102 INDIC_N_BLANK_3,
103 INDIC_N_BLANK_4, 103 INDIC_N_BLANK_4,
104 INDIC_N_BLANK_5, 104 INDIC_N_BLANK_5,
105 INDIC_N_BLANK_6, 105 INDIC_N_BLANK_6,
106 INDIC_N_BLANK_7, 106 INDIC_N_BLANK_7,
107 INDIC_N_BLANK_8, 107 INDIC_N_BLANK_8,
108 INDIC_N_BLANK_9, 108 INDIC_N_BLANK_9,
109 INDIC_N_BLANK_10, 109 INDIC_N_BLANK_10,
110 INDIC_N_BLANK_11, 110 INDIC_N_BLANK_11,
111 INDIC_N_BLANK_12, 111 INDIC_N_BLANK_12,
112 INDIC_N_BLANK_13, 112 INDIC_N_BLANK_13,
113 INDIC_N_BLANK_14, 113 INDIC_N_BLANK_14,
114 INDIC_N_BLANK_15, 114 INDIC_N_BLANK_15,
115 }; 115 };
116 116
117 enum lm3556_indic_period { 117 enum lm3556_indic_period {
118 INDIC_PERIOD_0 = 0, 118 INDIC_PERIOD_0 = 0,
119 INDIC_PERIOD_1, 119 INDIC_PERIOD_1,
120 INDIC_PERIOD_2, 120 INDIC_PERIOD_2,
121 INDIC_PERIOD_3, 121 INDIC_PERIOD_3,
122 INDIC_PERIOD_4, 122 INDIC_PERIOD_4,
123 INDIC_PERIOD_5, 123 INDIC_PERIOD_5,
124 INDIC_PERIOD_6, 124 INDIC_PERIOD_6,
125 INDIC_PERIOD_7, 125 INDIC_PERIOD_7,
126 }; 126 };
127 127
128 #define INDIC_PATTERN_SIZE 4 128 #define INDIC_PATTERN_SIZE 4
129 129
130 struct indicator { 130 struct indicator {
131 u8 blinking; 131 u8 blinking;
132 u8 period_cnt; 132 u8 period_cnt;
133 }; 133 };
134 134
135 /* indicator pattern data only for lm3556 */ 135 /* indicator pattern data only for lm3556 */
136 static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = { 136 static struct indicator indicator_pattern[INDIC_PATTERN_SIZE] = {
137 [0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1}, 137 [0] = {(INDIC_N_BLANK_1 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_1},
138 [1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2}, 138 [1] = {(INDIC_N_BLANK_15 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_2},
139 [2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4}, 139 [2] = {(INDIC_N_BLANK_10 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_4},
140 [3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7}, 140 [3] = {(INDIC_N_BLANK_5 << 4) | PULSE_TIME_32_MS, INDIC_PERIOD_7},
141 }; 141 };
142 142
143 static struct lm355x_reg_data lm3554_regs[REG_MAX] = { 143 static struct lm355x_reg_data lm3554_regs[REG_MAX] = {
144 [REG_FLAG] = {0xD0, 0xBF, 0}, 144 [REG_FLAG] = {0xD0, 0xBF, 0},
145 [REG_TORCH_CFG] = {0xE0, 0x80, 7}, 145 [REG_TORCH_CFG] = {0xE0, 0x80, 7},
146 [REG_TORCH_CTRL] = {0xA0, 0x38, 3}, 146 [REG_TORCH_CTRL] = {0xA0, 0x38, 3},
147 [REG_STROBE_CFG] = {0xE0, 0x04, 2}, 147 [REG_STROBE_CFG] = {0xE0, 0x04, 2},
148 [REG_FLASH_CTRL] = {0xB0, 0x78, 3}, 148 [REG_FLASH_CTRL] = {0xB0, 0x78, 3},
149 [REG_INDI_CFG] = {0xE0, 0x08, 3}, 149 [REG_INDI_CFG] = {0xE0, 0x08, 3},
150 [REG_INDI_CTRL] = {0xA0, 0xC0, 6}, 150 [REG_INDI_CTRL] = {0xA0, 0xC0, 6},
151 [REG_OPMODE] = {0xA0, 0x03, 0}, 151 [REG_OPMODE] = {0xA0, 0x03, 0},
152 }; 152 };
153 153
154 static struct lm355x_reg_data lm3556_regs[REG_MAX] = { 154 static struct lm355x_reg_data lm3556_regs[REG_MAX] = {
155 [REG_FLAG] = {0x0B, 0xFF, 0}, 155 [REG_FLAG] = {0x0B, 0xFF, 0},
156 [REG_TORCH_CFG] = {0x0A, 0x10, 4}, 156 [REG_TORCH_CFG] = {0x0A, 0x10, 4},
157 [REG_TORCH_CTRL] = {0x09, 0x70, 4}, 157 [REG_TORCH_CTRL] = {0x09, 0x70, 4},
158 [REG_STROBE_CFG] = {0x0A, 0x20, 5}, 158 [REG_STROBE_CFG] = {0x0A, 0x20, 5},
159 [REG_FLASH_CTRL] = {0x09, 0x0F, 0}, 159 [REG_FLASH_CTRL] = {0x09, 0x0F, 0},
160 [REG_INDI_CFG] = {0xFF, 0xFF, 0}, 160 [REG_INDI_CFG] = {0xFF, 0xFF, 0},
161 [REG_INDI_CTRL] = {0x09, 0x70, 4}, 161 [REG_INDI_CTRL] = {0x09, 0x70, 4},
162 [REG_OPMODE] = {0x0A, 0x03, 0}, 162 [REG_OPMODE] = {0x0A, 0x03, 0},
163 }; 163 };
164 164
165 static char lm355x_name[][I2C_NAME_SIZE] = { 165 static char lm355x_name[][I2C_NAME_SIZE] = {
166 [CHIP_LM3554] = LM3554_NAME, 166 [CHIP_LM3554] = LM3554_NAME,
167 [CHIP_LM3556] = LM3556_NAME, 167 [CHIP_LM3556] = LM3556_NAME,
168 }; 168 };
169 169
170 /* chip initialize */ 170 /* chip initialize */
171 static int lm355x_chip_init(struct lm355x_chip_data *chip) 171 static int lm355x_chip_init(struct lm355x_chip_data *chip)
172 { 172 {
173 int ret; 173 int ret;
174 unsigned int reg_val; 174 unsigned int reg_val;
175 struct lm355x_platform_data *pdata = chip->pdata; 175 struct lm355x_platform_data *pdata = chip->pdata;
176 176
177 /* input and output pins configuration */ 177 /* input and output pins configuration */
178 switch (chip->type) { 178 switch (chip->type) {
179 case CHIP_LM3554: 179 case CHIP_LM3554:
180 reg_val = pdata->pin_tx2 | pdata->ntc_pin; 180 reg_val = pdata->pin_tx2 | pdata->ntc_pin;
181 ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val); 181 ret = regmap_update_bits(chip->regmap, 0xE0, 0x28, reg_val);
182 if (ret < 0) 182 if (ret < 0)
183 goto out; 183 goto out;
184 reg_val = pdata->pass_mode; 184 reg_val = pdata->pass_mode;
185 ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val); 185 ret = regmap_update_bits(chip->regmap, 0xA0, 0x04, reg_val);
186 if (ret < 0) 186 if (ret < 0)
187 goto out; 187 goto out;
188 break; 188 break;
189 189
190 case CHIP_LM3556: 190 case CHIP_LM3556:
191 reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode; 191 reg_val = pdata->pin_tx2 | pdata->ntc_pin | pdata->pass_mode;
192 ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val); 192 ret = regmap_update_bits(chip->regmap, 0x0A, 0xC4, reg_val);
193 if (ret < 0) 193 if (ret < 0)
194 goto out; 194 goto out;
195 break; 195 break;
196 default: 196 default:
197 return -ENODATA; 197 return -ENODATA;
198 } 198 }
199 199
200 return ret; 200 return ret;
201 out: 201 out:
202 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 202 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
203 return ret; 203 return ret;
204 } 204 }
205 205
206 /* chip control */ 206 /* chip control */
207 static void lm355x_control(struct lm355x_chip_data *chip, 207 static void lm355x_control(struct lm355x_chip_data *chip,
208 u8 brightness, enum lm355x_mode opmode) 208 u8 brightness, enum lm355x_mode opmode)
209 { 209 {
210 int ret; 210 int ret;
211 unsigned int reg_val; 211 unsigned int reg_val;
212 struct lm355x_platform_data *pdata = chip->pdata; 212 struct lm355x_platform_data *pdata = chip->pdata;
213 struct lm355x_reg_data *preg = chip->regs; 213 struct lm355x_reg_data *preg = chip->regs;
214 214
215 ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag); 215 ret = regmap_read(chip->regmap, preg[REG_FLAG].regno, &chip->last_flag);
216 if (ret < 0) 216 if (ret < 0)
217 goto out; 217 goto out;
218 if (chip->last_flag & preg[REG_FLAG].mask) 218 if (chip->last_flag & preg[REG_FLAG].mask)
219 dev_info(chip->dev, "%s Last FLAG is 0x%x\n", 219 dev_info(chip->dev, "%s Last FLAG is 0x%x\n",
220 lm355x_name[chip->type], 220 lm355x_name[chip->type],
221 chip->last_flag & preg[REG_FLAG].mask); 221 chip->last_flag & preg[REG_FLAG].mask);
222 /* brightness 0 means shutdown */ 222 /* brightness 0 means shutdown */
223 if (!brightness) 223 if (!brightness)
224 opmode = MODE_SHDN; 224 opmode = MODE_SHDN;
225 225
226 switch (opmode) { 226 switch (opmode) {
227 case MODE_TORCH: 227 case MODE_TORCH:
228 ret = 228 ret =
229 regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno, 229 regmap_update_bits(chip->regmap, preg[REG_TORCH_CTRL].regno,
230 preg[REG_TORCH_CTRL].mask, 230 preg[REG_TORCH_CTRL].mask,
231 (brightness - 1) 231 (brightness - 1)
232 << preg[REG_TORCH_CTRL].shift); 232 << preg[REG_TORCH_CTRL].shift);
233 if (ret < 0) 233 if (ret < 0)
234 goto out; 234 goto out;
235 235
236 if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) { 236 if (pdata->pin_tx1 != LM355x_PIN_TORCH_DISABLE) {
237 ret = 237 ret =
238 regmap_update_bits(chip->regmap, 238 regmap_update_bits(chip->regmap,
239 preg[REG_TORCH_CFG].regno, 239 preg[REG_TORCH_CFG].regno,
240 preg[REG_TORCH_CFG].mask, 240 preg[REG_TORCH_CFG].mask,
241 0x01 << 241 0x01 <<
242 preg[REG_TORCH_CFG].shift); 242 preg[REG_TORCH_CFG].shift);
243 if (ret < 0) 243 if (ret < 0)
244 goto out; 244 goto out;
245 opmode = MODE_SHDN; 245 opmode = MODE_SHDN;
246 dev_info(chip->dev, 246 dev_info(chip->dev,
247 "torch brt is set - ext. torch pin mode\n"); 247 "torch brt is set - ext. torch pin mode\n");
248 } 248 }
249 break; 249 break;
250 250
251 case MODE_FLASH: 251 case MODE_FLASH:
252 252
253 ret = 253 ret =
254 regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno, 254 regmap_update_bits(chip->regmap, preg[REG_FLASH_CTRL].regno,
255 preg[REG_FLASH_CTRL].mask, 255 preg[REG_FLASH_CTRL].mask,
256 (brightness - 1) 256 (brightness - 1)
257 << preg[REG_FLASH_CTRL].shift); 257 << preg[REG_FLASH_CTRL].shift);
258 if (ret < 0) 258 if (ret < 0)
259 goto out; 259 goto out;
260 260
261 if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) { 261 if (pdata->pin_strobe != LM355x_PIN_STROBE_DISABLE) {
262 if (chip->type == CHIP_LM3554) 262 if (chip->type == CHIP_LM3554)
263 reg_val = 0x00; 263 reg_val = 0x00;
264 else 264 else
265 reg_val = 0x01; 265 reg_val = 0x01;
266 ret = 266 ret =
267 regmap_update_bits(chip->regmap, 267 regmap_update_bits(chip->regmap,
268 preg[REG_STROBE_CFG].regno, 268 preg[REG_STROBE_CFG].regno,
269 preg[REG_STROBE_CFG].mask, 269 preg[REG_STROBE_CFG].mask,
270 reg_val << 270 reg_val <<
271 preg[REG_STROBE_CFG].shift); 271 preg[REG_STROBE_CFG].shift);
272 if (ret < 0) 272 if (ret < 0)
273 goto out; 273 goto out;
274 opmode = MODE_SHDN; 274 opmode = MODE_SHDN;
275 dev_info(chip->dev, 275 dev_info(chip->dev,
276 "flash brt is set - ext. strobe pin mode\n"); 276 "flash brt is set - ext. strobe pin mode\n");
277 } 277 }
278 break; 278 break;
279 279
280 case MODE_INDIC: 280 case MODE_INDIC:
281 ret = 281 ret =
282 regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno, 282 regmap_update_bits(chip->regmap, preg[REG_INDI_CTRL].regno,
283 preg[REG_INDI_CTRL].mask, 283 preg[REG_INDI_CTRL].mask,
284 (brightness - 1) 284 (brightness - 1)
285 << preg[REG_INDI_CTRL].shift); 285 << preg[REG_INDI_CTRL].shift);
286 if (ret < 0) 286 if (ret < 0)
287 goto out; 287 goto out;
288 288
289 if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) { 289 if (pdata->pin_tx2 != LM355x_PIN_TX_DISABLE) {
290 ret = 290 ret =
291 regmap_update_bits(chip->regmap, 291 regmap_update_bits(chip->regmap,
292 preg[REG_INDI_CFG].regno, 292 preg[REG_INDI_CFG].regno,
293 preg[REG_INDI_CFG].mask, 293 preg[REG_INDI_CFG].mask,
294 0x01 << 294 0x01 <<
295 preg[REG_INDI_CFG].shift); 295 preg[REG_INDI_CFG].shift);
296 if (ret < 0) 296 if (ret < 0)
297 goto out; 297 goto out;
298 opmode = MODE_SHDN; 298 opmode = MODE_SHDN;
299 } 299 }
300 break; 300 break;
301 case MODE_SHDN: 301 case MODE_SHDN:
302 break; 302 break;
303 default: 303 default:
304 return; 304 return;
305 } 305 }
306 /* operation mode control */ 306 /* operation mode control */
307 ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno, 307 ret = regmap_update_bits(chip->regmap, preg[REG_OPMODE].regno,
308 preg[REG_OPMODE].mask, 308 preg[REG_OPMODE].mask,
309 opmode << preg[REG_OPMODE].shift); 309 opmode << preg[REG_OPMODE].shift);
310 if (ret < 0) 310 if (ret < 0)
311 goto out; 311 goto out;
312 return; 312 return;
313 out: 313 out:
314 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 314 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
315 return; 315 return;
316 } 316 }
317 317
318 /* torch */ 318 /* torch */
319 static void lm355x_deferred_torch_brightness_set(struct work_struct *work) 319 static void lm355x_deferred_torch_brightness_set(struct work_struct *work)
320 { 320 {
321 struct lm355x_chip_data *chip = 321 struct lm355x_chip_data *chip =
322 container_of(work, struct lm355x_chip_data, work_torch); 322 container_of(work, struct lm355x_chip_data, work_torch);
323 323
324 mutex_lock(&chip->lock); 324 mutex_lock(&chip->lock);
325 lm355x_control(chip, chip->br_torch, MODE_TORCH); 325 lm355x_control(chip, chip->br_torch, MODE_TORCH);
326 mutex_unlock(&chip->lock); 326 mutex_unlock(&chip->lock);
327 } 327 }
328 328
329 static void lm355x_torch_brightness_set(struct led_classdev *cdev, 329 static void lm355x_torch_brightness_set(struct led_classdev *cdev,
330 enum led_brightness brightness) 330 enum led_brightness brightness)
331 { 331 {
332 struct lm355x_chip_data *chip = 332 struct lm355x_chip_data *chip =
333 container_of(cdev, struct lm355x_chip_data, cdev_torch); 333 container_of(cdev, struct lm355x_chip_data, cdev_torch);
334 334
335 chip->br_torch = brightness; 335 chip->br_torch = brightness;
336 schedule_work(&chip->work_torch); 336 schedule_work(&chip->work_torch);
337 } 337 }
338 338
339 /* flash */ 339 /* flash */
340 static void lm355x_deferred_strobe_brightness_set(struct work_struct *work) 340 static void lm355x_deferred_strobe_brightness_set(struct work_struct *work)
341 { 341 {
342 struct lm355x_chip_data *chip = 342 struct lm355x_chip_data *chip =
343 container_of(work, struct lm355x_chip_data, work_flash); 343 container_of(work, struct lm355x_chip_data, work_flash);
344 344
345 mutex_lock(&chip->lock); 345 mutex_lock(&chip->lock);
346 lm355x_control(chip, chip->br_flash, MODE_FLASH); 346 lm355x_control(chip, chip->br_flash, MODE_FLASH);
347 mutex_unlock(&chip->lock); 347 mutex_unlock(&chip->lock);
348 } 348 }
349 349
350 static void lm355x_strobe_brightness_set(struct led_classdev *cdev, 350 static void lm355x_strobe_brightness_set(struct led_classdev *cdev,
351 enum led_brightness brightness) 351 enum led_brightness brightness)
352 { 352 {
353 struct lm355x_chip_data *chip = 353 struct lm355x_chip_data *chip =
354 container_of(cdev, struct lm355x_chip_data, cdev_flash); 354 container_of(cdev, struct lm355x_chip_data, cdev_flash);
355 355
356 chip->br_flash = brightness; 356 chip->br_flash = brightness;
357 schedule_work(&chip->work_flash); 357 schedule_work(&chip->work_flash);
358 } 358 }
359 359
360 /* indicator */ 360 /* indicator */
361 static void lm355x_deferred_indicator_brightness_set(struct work_struct *work) 361 static void lm355x_deferred_indicator_brightness_set(struct work_struct *work)
362 { 362 {
363 struct lm355x_chip_data *chip = 363 struct lm355x_chip_data *chip =
364 container_of(work, struct lm355x_chip_data, work_indicator); 364 container_of(work, struct lm355x_chip_data, work_indicator);
365 365
366 mutex_lock(&chip->lock); 366 mutex_lock(&chip->lock);
367 lm355x_control(chip, chip->br_indicator, MODE_INDIC); 367 lm355x_control(chip, chip->br_indicator, MODE_INDIC);
368 mutex_unlock(&chip->lock); 368 mutex_unlock(&chip->lock);
369 } 369 }
370 370
371 static void lm355x_indicator_brightness_set(struct led_classdev *cdev, 371 static void lm355x_indicator_brightness_set(struct led_classdev *cdev,
372 enum led_brightness brightness) 372 enum led_brightness brightness)
373 { 373 {
374 struct lm355x_chip_data *chip = 374 struct lm355x_chip_data *chip =
375 container_of(cdev, struct lm355x_chip_data, cdev_indicator); 375 container_of(cdev, struct lm355x_chip_data, cdev_indicator);
376 376
377 chip->br_indicator = brightness; 377 chip->br_indicator = brightness;
378 schedule_work(&chip->work_indicator); 378 schedule_work(&chip->work_indicator);
379 } 379 }
380 380
381 /* indicator pattern only for lm3556*/ 381 /* indicator pattern only for lm3556*/
382 static ssize_t lm3556_indicator_pattern_store(struct device *dev, 382 static ssize_t lm3556_indicator_pattern_store(struct device *dev,
383 struct device_attribute *attr, 383 struct device_attribute *attr,
384 const char *buf, size_t size) 384 const char *buf, size_t size)
385 { 385 {
386 ssize_t ret; 386 ssize_t ret;
387 struct led_classdev *led_cdev = dev_get_drvdata(dev); 387 struct led_classdev *led_cdev = dev_get_drvdata(dev);
388 struct lm355x_chip_data *chip = 388 struct lm355x_chip_data *chip =
389 container_of(led_cdev, struct lm355x_chip_data, cdev_indicator); 389 container_of(led_cdev, struct lm355x_chip_data, cdev_indicator);
390 unsigned int state; 390 unsigned int state;
391 391
392 ret = kstrtouint(buf, 10, &state); 392 ret = kstrtouint(buf, 10, &state);
393 if (ret) 393 if (ret)
394 goto out; 394 goto out;
395 if (state > INDIC_PATTERN_SIZE - 1) 395 if (state > INDIC_PATTERN_SIZE - 1)
396 state = INDIC_PATTERN_SIZE - 1; 396 state = INDIC_PATTERN_SIZE - 1;
397 397
398 ret = regmap_write(chip->regmap, 0x04, 398 ret = regmap_write(chip->regmap, 0x04,
399 indicator_pattern[state].blinking); 399 indicator_pattern[state].blinking);
400 if (ret < 0) 400 if (ret < 0)
401 goto out; 401 goto out;
402 402
403 ret = regmap_write(chip->regmap, 0x05, 403 ret = regmap_write(chip->regmap, 0x05,
404 indicator_pattern[state].period_cnt); 404 indicator_pattern[state].period_cnt);
405 if (ret < 0) 405 if (ret < 0)
406 goto out; 406 goto out;
407 407
408 return size; 408 return size;
409 out: 409 out:
410 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 410 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
411 return ret; 411 return ret;
412 } 412 }
413 413
414 static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store); 414 static DEVICE_ATTR(pattern, S_IWUSR, NULL, lm3556_indicator_pattern_store);
415 415
416 static const struct regmap_config lm355x_regmap = { 416 static const struct regmap_config lm355x_regmap = {
417 .reg_bits = 8, 417 .reg_bits = 8,
418 .val_bits = 8, 418 .val_bits = 8,
419 .max_register = 0xFF, 419 .max_register = 0xFF,
420 }; 420 };
421 421
422 /* module initialize */ 422 /* module initialize */
423 static int lm355x_probe(struct i2c_client *client, 423 static int lm355x_probe(struct i2c_client *client,
424 const struct i2c_device_id *id) 424 const struct i2c_device_id *id)
425 { 425 {
426 struct lm355x_platform_data *pdata = client->dev.platform_data; 426 struct lm355x_platform_data *pdata = dev_get_platdata(&client->dev);
427 struct lm355x_chip_data *chip; 427 struct lm355x_chip_data *chip;
428 428
429 int err; 429 int err;
430 430
431 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 431 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
432 dev_err(&client->dev, "i2c functionality check fail.\n"); 432 dev_err(&client->dev, "i2c functionality check fail.\n");
433 return -EOPNOTSUPP; 433 return -EOPNOTSUPP;
434 } 434 }
435 435
436 if (pdata == NULL) { 436 if (pdata == NULL) {
437 dev_err(&client->dev, "needs Platform Data.\n"); 437 dev_err(&client->dev, "needs Platform Data.\n");
438 return -ENODATA; 438 return -ENODATA;
439 } 439 }
440 440
441 chip = devm_kzalloc(&client->dev, 441 chip = devm_kzalloc(&client->dev,
442 sizeof(struct lm355x_chip_data), GFP_KERNEL); 442 sizeof(struct lm355x_chip_data), GFP_KERNEL);
443 if (!chip) 443 if (!chip)
444 return -ENOMEM; 444 return -ENOMEM;
445 445
446 chip->dev = &client->dev; 446 chip->dev = &client->dev;
447 chip->type = id->driver_data; 447 chip->type = id->driver_data;
448 switch (id->driver_data) { 448 switch (id->driver_data) {
449 case CHIP_LM3554: 449 case CHIP_LM3554:
450 chip->regs = lm3554_regs; 450 chip->regs = lm3554_regs;
451 break; 451 break;
452 case CHIP_LM3556: 452 case CHIP_LM3556:
453 chip->regs = lm3556_regs; 453 chip->regs = lm3556_regs;
454 break; 454 break;
455 default: 455 default:
456 return -ENOSYS; 456 return -ENOSYS;
457 } 457 }
458 chip->pdata = pdata; 458 chip->pdata = pdata;
459 459
460 chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap); 460 chip->regmap = devm_regmap_init_i2c(client, &lm355x_regmap);
461 if (IS_ERR(chip->regmap)) { 461 if (IS_ERR(chip->regmap)) {
462 err = PTR_ERR(chip->regmap); 462 err = PTR_ERR(chip->regmap);
463 dev_err(&client->dev, 463 dev_err(&client->dev,
464 "Failed to allocate register map: %d\n", err); 464 "Failed to allocate register map: %d\n", err);
465 return err; 465 return err;
466 } 466 }
467 467
468 mutex_init(&chip->lock); 468 mutex_init(&chip->lock);
469 i2c_set_clientdata(client, chip); 469 i2c_set_clientdata(client, chip);
470 470
471 err = lm355x_chip_init(chip); 471 err = lm355x_chip_init(chip);
472 if (err < 0) 472 if (err < 0)
473 goto err_out; 473 goto err_out;
474 474
475 /* flash */ 475 /* flash */
476 INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set); 476 INIT_WORK(&chip->work_flash, lm355x_deferred_strobe_brightness_set);
477 chip->cdev_flash.name = "flash"; 477 chip->cdev_flash.name = "flash";
478 chip->cdev_flash.max_brightness = 16; 478 chip->cdev_flash.max_brightness = 16;
479 chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set; 479 chip->cdev_flash.brightness_set = lm355x_strobe_brightness_set;
480 chip->cdev_flash.default_trigger = "flash"; 480 chip->cdev_flash.default_trigger = "flash";
481 err = led_classdev_register((struct device *) 481 err = led_classdev_register((struct device *)
482 &client->dev, &chip->cdev_flash); 482 &client->dev, &chip->cdev_flash);
483 if (err < 0) 483 if (err < 0)
484 goto err_out; 484 goto err_out;
485 /* torch */ 485 /* torch */
486 INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set); 486 INIT_WORK(&chip->work_torch, lm355x_deferred_torch_brightness_set);
487 chip->cdev_torch.name = "torch"; 487 chip->cdev_torch.name = "torch";
488 chip->cdev_torch.max_brightness = 8; 488 chip->cdev_torch.max_brightness = 8;
489 chip->cdev_torch.brightness_set = lm355x_torch_brightness_set; 489 chip->cdev_torch.brightness_set = lm355x_torch_brightness_set;
490 chip->cdev_torch.default_trigger = "torch"; 490 chip->cdev_torch.default_trigger = "torch";
491 err = led_classdev_register((struct device *) 491 err = led_classdev_register((struct device *)
492 &client->dev, &chip->cdev_torch); 492 &client->dev, &chip->cdev_torch);
493 if (err < 0) 493 if (err < 0)
494 goto err_create_torch_file; 494 goto err_create_torch_file;
495 /* indicator */ 495 /* indicator */
496 INIT_WORK(&chip->work_indicator, 496 INIT_WORK(&chip->work_indicator,
497 lm355x_deferred_indicator_brightness_set); 497 lm355x_deferred_indicator_brightness_set);
498 chip->cdev_indicator.name = "indicator"; 498 chip->cdev_indicator.name = "indicator";
499 if (id->driver_data == CHIP_LM3554) 499 if (id->driver_data == CHIP_LM3554)
500 chip->cdev_indicator.max_brightness = 4; 500 chip->cdev_indicator.max_brightness = 4;
501 else 501 else
502 chip->cdev_indicator.max_brightness = 8; 502 chip->cdev_indicator.max_brightness = 8;
503 chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set; 503 chip->cdev_indicator.brightness_set = lm355x_indicator_brightness_set;
504 err = led_classdev_register((struct device *) 504 err = led_classdev_register((struct device *)
505 &client->dev, &chip->cdev_indicator); 505 &client->dev, &chip->cdev_indicator);
506 if (err < 0) 506 if (err < 0)
507 goto err_create_indicator_file; 507 goto err_create_indicator_file;
508 /* indicator pattern control only for LM3554 */ 508 /* indicator pattern control only for LM3554 */
509 if (id->driver_data == CHIP_LM3556) { 509 if (id->driver_data == CHIP_LM3556) {
510 err = 510 err =
511 device_create_file(chip->cdev_indicator.dev, 511 device_create_file(chip->cdev_indicator.dev,
512 &dev_attr_pattern); 512 &dev_attr_pattern);
513 if (err < 0) 513 if (err < 0)
514 goto err_create_pattern_file; 514 goto err_create_pattern_file;
515 } 515 }
516 516
517 dev_info(&client->dev, "%s is initialized\n", 517 dev_info(&client->dev, "%s is initialized\n",
518 lm355x_name[id->driver_data]); 518 lm355x_name[id->driver_data]);
519 return 0; 519 return 0;
520 520
521 err_create_pattern_file: 521 err_create_pattern_file:
522 led_classdev_unregister(&chip->cdev_indicator); 522 led_classdev_unregister(&chip->cdev_indicator);
523 err_create_indicator_file: 523 err_create_indicator_file:
524 led_classdev_unregister(&chip->cdev_torch); 524 led_classdev_unregister(&chip->cdev_torch);
525 err_create_torch_file: 525 err_create_torch_file:
526 led_classdev_unregister(&chip->cdev_flash); 526 led_classdev_unregister(&chip->cdev_flash);
527 err_out: 527 err_out:
528 return err; 528 return err;
529 } 529 }
530 530
531 static int lm355x_remove(struct i2c_client *client) 531 static int lm355x_remove(struct i2c_client *client)
532 { 532 {
533 struct lm355x_chip_data *chip = i2c_get_clientdata(client); 533 struct lm355x_chip_data *chip = i2c_get_clientdata(client);
534 struct lm355x_reg_data *preg = chip->regs; 534 struct lm355x_reg_data *preg = chip->regs;
535 535
536 regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0); 536 regmap_write(chip->regmap, preg[REG_OPMODE].regno, 0);
537 if (chip->type == CHIP_LM3556) 537 if (chip->type == CHIP_LM3556)
538 device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern); 538 device_remove_file(chip->cdev_indicator.dev, &dev_attr_pattern);
539 led_classdev_unregister(&chip->cdev_indicator); 539 led_classdev_unregister(&chip->cdev_indicator);
540 flush_work(&chip->work_indicator); 540 flush_work(&chip->work_indicator);
541 led_classdev_unregister(&chip->cdev_torch); 541 led_classdev_unregister(&chip->cdev_torch);
542 flush_work(&chip->work_torch); 542 flush_work(&chip->work_torch);
543 led_classdev_unregister(&chip->cdev_flash); 543 led_classdev_unregister(&chip->cdev_flash);
544 flush_work(&chip->work_flash); 544 flush_work(&chip->work_flash);
545 dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]); 545 dev_info(&client->dev, "%s is removed\n", lm355x_name[chip->type]);
546 546
547 return 0; 547 return 0;
548 } 548 }
549 549
550 static const struct i2c_device_id lm355x_id[] = { 550 static const struct i2c_device_id lm355x_id[] = {
551 {LM3554_NAME, CHIP_LM3554}, 551 {LM3554_NAME, CHIP_LM3554},
552 {LM3556_NAME, CHIP_LM3556}, 552 {LM3556_NAME, CHIP_LM3556},
553 {} 553 {}
554 }; 554 };
555 555
556 MODULE_DEVICE_TABLE(i2c, lm355x_id); 556 MODULE_DEVICE_TABLE(i2c, lm355x_id);
557 557
558 static struct i2c_driver lm355x_i2c_driver = { 558 static struct i2c_driver lm355x_i2c_driver = {
559 .driver = { 559 .driver = {
560 .name = LM355x_NAME, 560 .name = LM355x_NAME,
561 .owner = THIS_MODULE, 561 .owner = THIS_MODULE,
562 .pm = NULL, 562 .pm = NULL,
563 }, 563 },
564 .probe = lm355x_probe, 564 .probe = lm355x_probe,
565 .remove = lm355x_remove, 565 .remove = lm355x_remove,
566 .id_table = lm355x_id, 566 .id_table = lm355x_id,
567 }; 567 };
568 568
569 module_i2c_driver(lm355x_i2c_driver); 569 module_i2c_driver(lm355x_i2c_driver);
570 570
571 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x"); 571 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM355x");
572 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); 572 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
573 MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); 573 MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
574 MODULE_LICENSE("GPL v2"); 574 MODULE_LICENSE("GPL v2");
575 575
drivers/leds/leds-lm3642.c
1 /* 1 /*
2 * Simple driver for Texas Instruments LM3642 LED Flash driver chip 2 * Simple driver for Texas Instruments LM3642 LED Flash driver chip
3 * Copyright (C) 2012 Texas Instruments 3 * Copyright (C) 2012 Texas Instruments
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as 6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
8 * 8 *
9 */ 9 */
10 #include <linux/module.h> 10 #include <linux/module.h>
11 #include <linux/delay.h> 11 #include <linux/delay.h>
12 #include <linux/i2c.h> 12 #include <linux/i2c.h>
13 #include <linux/leds.h> 13 #include <linux/leds.h>
14 #include <linux/slab.h> 14 #include <linux/slab.h>
15 #include <linux/platform_device.h> 15 #include <linux/platform_device.h>
16 #include <linux/fs.h> 16 #include <linux/fs.h>
17 #include <linux/regmap.h> 17 #include <linux/regmap.h>
18 #include <linux/workqueue.h> 18 #include <linux/workqueue.h>
19 #include <linux/platform_data/leds-lm3642.h> 19 #include <linux/platform_data/leds-lm3642.h>
20 20
21 #define REG_FILT_TIME (0x0) 21 #define REG_FILT_TIME (0x0)
22 #define REG_IVFM_MODE (0x1) 22 #define REG_IVFM_MODE (0x1)
23 #define REG_TORCH_TIME (0x6) 23 #define REG_TORCH_TIME (0x6)
24 #define REG_FLASH (0x8) 24 #define REG_FLASH (0x8)
25 #define REG_I_CTRL (0x9) 25 #define REG_I_CTRL (0x9)
26 #define REG_ENABLE (0xA) 26 #define REG_ENABLE (0xA)
27 #define REG_FLAG (0xB) 27 #define REG_FLAG (0xB)
28 #define REG_MAX (0xB) 28 #define REG_MAX (0xB)
29 29
30 #define UVLO_EN_SHIFT (7) 30 #define UVLO_EN_SHIFT (7)
31 #define IVM_D_TH_SHIFT (2) 31 #define IVM_D_TH_SHIFT (2)
32 #define TORCH_RAMP_UP_TIME_SHIFT (3) 32 #define TORCH_RAMP_UP_TIME_SHIFT (3)
33 #define TORCH_RAMP_DN_TIME_SHIFT (0) 33 #define TORCH_RAMP_DN_TIME_SHIFT (0)
34 #define INDUCTOR_I_LIMIT_SHIFT (6) 34 #define INDUCTOR_I_LIMIT_SHIFT (6)
35 #define FLASH_RAMP_TIME_SHIFT (3) 35 #define FLASH_RAMP_TIME_SHIFT (3)
36 #define FLASH_TOUT_TIME_SHIFT (0) 36 #define FLASH_TOUT_TIME_SHIFT (0)
37 #define TORCH_I_SHIFT (4) 37 #define TORCH_I_SHIFT (4)
38 #define FLASH_I_SHIFT (0) 38 #define FLASH_I_SHIFT (0)
39 #define IVFM_SHIFT (7) 39 #define IVFM_SHIFT (7)
40 #define TX_PIN_EN_SHIFT (6) 40 #define TX_PIN_EN_SHIFT (6)
41 #define STROBE_PIN_EN_SHIFT (5) 41 #define STROBE_PIN_EN_SHIFT (5)
42 #define TORCH_PIN_EN_SHIFT (4) 42 #define TORCH_PIN_EN_SHIFT (4)
43 #define MODE_BITS_SHIFT (0) 43 #define MODE_BITS_SHIFT (0)
44 44
45 #define UVLO_EN_MASK (0x1) 45 #define UVLO_EN_MASK (0x1)
46 #define IVM_D_TH_MASK (0x7) 46 #define IVM_D_TH_MASK (0x7)
47 #define TORCH_RAMP_UP_TIME_MASK (0x7) 47 #define TORCH_RAMP_UP_TIME_MASK (0x7)
48 #define TORCH_RAMP_DN_TIME_MASK (0x7) 48 #define TORCH_RAMP_DN_TIME_MASK (0x7)
49 #define INDUCTOR_I_LIMIT_MASK (0x1) 49 #define INDUCTOR_I_LIMIT_MASK (0x1)
50 #define FLASH_RAMP_TIME_MASK (0x7) 50 #define FLASH_RAMP_TIME_MASK (0x7)
51 #define FLASH_TOUT_TIME_MASK (0x7) 51 #define FLASH_TOUT_TIME_MASK (0x7)
52 #define TORCH_I_MASK (0x7) 52 #define TORCH_I_MASK (0x7)
53 #define FLASH_I_MASK (0xF) 53 #define FLASH_I_MASK (0xF)
54 #define IVFM_MASK (0x1) 54 #define IVFM_MASK (0x1)
55 #define TX_PIN_EN_MASK (0x1) 55 #define TX_PIN_EN_MASK (0x1)
56 #define STROBE_PIN_EN_MASK (0x1) 56 #define STROBE_PIN_EN_MASK (0x1)
57 #define TORCH_PIN_EN_MASK (0x1) 57 #define TORCH_PIN_EN_MASK (0x1)
58 #define MODE_BITS_MASK (0x73) 58 #define MODE_BITS_MASK (0x73)
59 #define EX_PIN_CONTROL_MASK (0x71) 59 #define EX_PIN_CONTROL_MASK (0x71)
60 #define EX_PIN_ENABLE_MASK (0x70) 60 #define EX_PIN_ENABLE_MASK (0x70)
61 61
62 enum lm3642_mode { 62 enum lm3642_mode {
63 MODES_STASNDBY = 0, 63 MODES_STASNDBY = 0,
64 MODES_INDIC, 64 MODES_INDIC,
65 MODES_TORCH, 65 MODES_TORCH,
66 MODES_FLASH 66 MODES_FLASH
67 }; 67 };
68 68
69 struct lm3642_chip_data { 69 struct lm3642_chip_data {
70 struct device *dev; 70 struct device *dev;
71 71
72 struct led_classdev cdev_flash; 72 struct led_classdev cdev_flash;
73 struct led_classdev cdev_torch; 73 struct led_classdev cdev_torch;
74 struct led_classdev cdev_indicator; 74 struct led_classdev cdev_indicator;
75 75
76 struct work_struct work_flash; 76 struct work_struct work_flash;
77 struct work_struct work_torch; 77 struct work_struct work_torch;
78 struct work_struct work_indicator; 78 struct work_struct work_indicator;
79 79
80 u8 br_flash; 80 u8 br_flash;
81 u8 br_torch; 81 u8 br_torch;
82 u8 br_indicator; 82 u8 br_indicator;
83 83
84 enum lm3642_torch_pin_enable torch_pin; 84 enum lm3642_torch_pin_enable torch_pin;
85 enum lm3642_strobe_pin_enable strobe_pin; 85 enum lm3642_strobe_pin_enable strobe_pin;
86 enum lm3642_tx_pin_enable tx_pin; 86 enum lm3642_tx_pin_enable tx_pin;
87 87
88 struct lm3642_platform_data *pdata; 88 struct lm3642_platform_data *pdata;
89 struct regmap *regmap; 89 struct regmap *regmap;
90 struct mutex lock; 90 struct mutex lock;
91 91
92 unsigned int last_flag; 92 unsigned int last_flag;
93 }; 93 };
94 94
95 /* chip initialize */ 95 /* chip initialize */
96 static int lm3642_chip_init(struct lm3642_chip_data *chip) 96 static int lm3642_chip_init(struct lm3642_chip_data *chip)
97 { 97 {
98 int ret; 98 int ret;
99 struct lm3642_platform_data *pdata = chip->pdata; 99 struct lm3642_platform_data *pdata = chip->pdata;
100 100
101 /* set enable register */ 101 /* set enable register */
102 ret = regmap_update_bits(chip->regmap, REG_ENABLE, EX_PIN_ENABLE_MASK, 102 ret = regmap_update_bits(chip->regmap, REG_ENABLE, EX_PIN_ENABLE_MASK,
103 pdata->tx_pin); 103 pdata->tx_pin);
104 if (ret < 0) 104 if (ret < 0)
105 dev_err(chip->dev, "Failed to update REG_ENABLE Register\n"); 105 dev_err(chip->dev, "Failed to update REG_ENABLE Register\n");
106 return ret; 106 return ret;
107 } 107 }
108 108
109 /* chip control */ 109 /* chip control */
110 static int lm3642_control(struct lm3642_chip_data *chip, 110 static int lm3642_control(struct lm3642_chip_data *chip,
111 u8 brightness, enum lm3642_mode opmode) 111 u8 brightness, enum lm3642_mode opmode)
112 { 112 {
113 int ret; 113 int ret;
114 114
115 ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag); 115 ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
116 if (ret < 0) { 116 if (ret < 0) {
117 dev_err(chip->dev, "Failed to read REG_FLAG Register\n"); 117 dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
118 goto out; 118 goto out;
119 } 119 }
120 120
121 if (chip->last_flag) 121 if (chip->last_flag)
122 dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag); 122 dev_info(chip->dev, "Last FLAG is 0x%x\n", chip->last_flag);
123 123
124 /* brightness 0 means off-state */ 124 /* brightness 0 means off-state */
125 if (!brightness) 125 if (!brightness)
126 opmode = MODES_STASNDBY; 126 opmode = MODES_STASNDBY;
127 127
128 switch (opmode) { 128 switch (opmode) {
129 case MODES_TORCH: 129 case MODES_TORCH:
130 ret = regmap_update_bits(chip->regmap, REG_I_CTRL, 130 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
131 TORCH_I_MASK << TORCH_I_SHIFT, 131 TORCH_I_MASK << TORCH_I_SHIFT,
132 (brightness - 1) << TORCH_I_SHIFT); 132 (brightness - 1) << TORCH_I_SHIFT);
133 133
134 if (chip->torch_pin) 134 if (chip->torch_pin)
135 opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT); 135 opmode |= (TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT);
136 break; 136 break;
137 137
138 case MODES_FLASH: 138 case MODES_FLASH:
139 ret = regmap_update_bits(chip->regmap, REG_I_CTRL, 139 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
140 FLASH_I_MASK << FLASH_I_SHIFT, 140 FLASH_I_MASK << FLASH_I_SHIFT,
141 (brightness - 1) << FLASH_I_SHIFT); 141 (brightness - 1) << FLASH_I_SHIFT);
142 142
143 if (chip->strobe_pin) 143 if (chip->strobe_pin)
144 opmode |= (STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT); 144 opmode |= (STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT);
145 break; 145 break;
146 146
147 case MODES_INDIC: 147 case MODES_INDIC:
148 ret = regmap_update_bits(chip->regmap, REG_I_CTRL, 148 ret = regmap_update_bits(chip->regmap, REG_I_CTRL,
149 TORCH_I_MASK << TORCH_I_SHIFT, 149 TORCH_I_MASK << TORCH_I_SHIFT,
150 (brightness - 1) << TORCH_I_SHIFT); 150 (brightness - 1) << TORCH_I_SHIFT);
151 break; 151 break;
152 152
153 case MODES_STASNDBY: 153 case MODES_STASNDBY:
154 154
155 break; 155 break;
156 156
157 default: 157 default:
158 return ret; 158 return ret;
159 } 159 }
160 if (ret < 0) { 160 if (ret < 0) {
161 dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n"); 161 dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
162 goto out; 162 goto out;
163 } 163 }
164 164
165 if (chip->tx_pin) 165 if (chip->tx_pin)
166 opmode |= (TX_PIN_EN_MASK << TX_PIN_EN_SHIFT); 166 opmode |= (TX_PIN_EN_MASK << TX_PIN_EN_SHIFT);
167 167
168 ret = regmap_update_bits(chip->regmap, REG_ENABLE, 168 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
169 MODE_BITS_MASK << MODE_BITS_SHIFT, 169 MODE_BITS_MASK << MODE_BITS_SHIFT,
170 opmode << MODE_BITS_SHIFT); 170 opmode << MODE_BITS_SHIFT);
171 out: 171 out:
172 return ret; 172 return ret;
173 } 173 }
174 174
175 /* torch */ 175 /* torch */
176 176
177 /* torch pin config for lm3642*/ 177 /* torch pin config for lm3642*/
178 static ssize_t lm3642_torch_pin_store(struct device *dev, 178 static ssize_t lm3642_torch_pin_store(struct device *dev,
179 struct device_attribute *attr, 179 struct device_attribute *attr,
180 const char *buf, size_t size) 180 const char *buf, size_t size)
181 { 181 {
182 ssize_t ret; 182 ssize_t ret;
183 struct led_classdev *led_cdev = dev_get_drvdata(dev); 183 struct led_classdev *led_cdev = dev_get_drvdata(dev);
184 struct lm3642_chip_data *chip = 184 struct lm3642_chip_data *chip =
185 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator); 185 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
186 unsigned int state; 186 unsigned int state;
187 187
188 ret = kstrtouint(buf, 10, &state); 188 ret = kstrtouint(buf, 10, &state);
189 if (ret) 189 if (ret)
190 goto out_strtoint; 190 goto out_strtoint;
191 if (state != 0) 191 if (state != 0)
192 state = 0x01 << TORCH_PIN_EN_SHIFT; 192 state = 0x01 << TORCH_PIN_EN_SHIFT;
193 193
194 chip->torch_pin = state; 194 chip->torch_pin = state;
195 ret = regmap_update_bits(chip->regmap, REG_ENABLE, 195 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
196 TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT, 196 TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT,
197 state); 197 state);
198 if (ret < 0) 198 if (ret < 0)
199 goto out; 199 goto out;
200 200
201 return size; 201 return size;
202 out: 202 out:
203 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 203 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
204 return ret; 204 return ret;
205 out_strtoint: 205 out_strtoint:
206 dev_err(chip->dev, "%s: fail to change str to int\n", __func__); 206 dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
207 return ret; 207 return ret;
208 } 208 }
209 209
210 static DEVICE_ATTR(torch_pin, S_IWUSR, NULL, lm3642_torch_pin_store); 210 static DEVICE_ATTR(torch_pin, S_IWUSR, NULL, lm3642_torch_pin_store);
211 211
212 static void lm3642_deferred_torch_brightness_set(struct work_struct *work) 212 static void lm3642_deferred_torch_brightness_set(struct work_struct *work)
213 { 213 {
214 struct lm3642_chip_data *chip = 214 struct lm3642_chip_data *chip =
215 container_of(work, struct lm3642_chip_data, work_torch); 215 container_of(work, struct lm3642_chip_data, work_torch);
216 216
217 mutex_lock(&chip->lock); 217 mutex_lock(&chip->lock);
218 lm3642_control(chip, chip->br_torch, MODES_TORCH); 218 lm3642_control(chip, chip->br_torch, MODES_TORCH);
219 mutex_unlock(&chip->lock); 219 mutex_unlock(&chip->lock);
220 } 220 }
221 221
222 static void lm3642_torch_brightness_set(struct led_classdev *cdev, 222 static void lm3642_torch_brightness_set(struct led_classdev *cdev,
223 enum led_brightness brightness) 223 enum led_brightness brightness)
224 { 224 {
225 struct lm3642_chip_data *chip = 225 struct lm3642_chip_data *chip =
226 container_of(cdev, struct lm3642_chip_data, cdev_torch); 226 container_of(cdev, struct lm3642_chip_data, cdev_torch);
227 227
228 chip->br_torch = brightness; 228 chip->br_torch = brightness;
229 schedule_work(&chip->work_torch); 229 schedule_work(&chip->work_torch);
230 } 230 }
231 231
232 /* flash */ 232 /* flash */
233 233
234 /* strobe pin config for lm3642*/ 234 /* strobe pin config for lm3642*/
235 static ssize_t lm3642_strobe_pin_store(struct device *dev, 235 static ssize_t lm3642_strobe_pin_store(struct device *dev,
236 struct device_attribute *attr, 236 struct device_attribute *attr,
237 const char *buf, size_t size) 237 const char *buf, size_t size)
238 { 238 {
239 ssize_t ret; 239 ssize_t ret;
240 struct led_classdev *led_cdev = dev_get_drvdata(dev); 240 struct led_classdev *led_cdev = dev_get_drvdata(dev);
241 struct lm3642_chip_data *chip = 241 struct lm3642_chip_data *chip =
242 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator); 242 container_of(led_cdev, struct lm3642_chip_data, cdev_indicator);
243 unsigned int state; 243 unsigned int state;
244 244
245 ret = kstrtouint(buf, 10, &state); 245 ret = kstrtouint(buf, 10, &state);
246 if (ret) 246 if (ret)
247 goto out_strtoint; 247 goto out_strtoint;
248 if (state != 0) 248 if (state != 0)
249 state = 0x01 << STROBE_PIN_EN_SHIFT; 249 state = 0x01 << STROBE_PIN_EN_SHIFT;
250 250
251 chip->strobe_pin = state; 251 chip->strobe_pin = state;
252 ret = regmap_update_bits(chip->regmap, REG_ENABLE, 252 ret = regmap_update_bits(chip->regmap, REG_ENABLE,
253 STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT, 253 STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT,
254 state); 254 state);
255 if (ret < 0) 255 if (ret < 0)
256 goto out; 256 goto out;
257 257
258 return size; 258 return size;
259 out: 259 out:
260 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__); 260 dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
261 return ret; 261 return ret;
262 out_strtoint: 262 out_strtoint:
263 dev_err(chip->dev, "%s: fail to change str to int\n", __func__); 263 dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
264 return ret; 264 return ret;
265 } 265 }
266 266
267 static DEVICE_ATTR(strobe_pin, S_IWUSR, NULL, lm3642_strobe_pin_store); 267 static DEVICE_ATTR(strobe_pin, S_IWUSR, NULL, lm3642_strobe_pin_store);
268 268
269 static void lm3642_deferred_strobe_brightness_set(struct work_struct *work) 269 static void lm3642_deferred_strobe_brightness_set(struct work_struct *work)
270 { 270 {
271 struct lm3642_chip_data *chip = 271 struct lm3642_chip_data *chip =
272 container_of(work, struct lm3642_chip_data, work_flash); 272 container_of(work, struct lm3642_chip_data, work_flash);
273 273
274 mutex_lock(&chip->lock); 274 mutex_lock(&chip->lock);
275 lm3642_control(chip, chip->br_flash, MODES_FLASH); 275 lm3642_control(chip, chip->br_flash, MODES_FLASH);
276 mutex_unlock(&chip->lock); 276 mutex_unlock(&chip->lock);
277 } 277 }
278 278
279 static void lm3642_strobe_brightness_set(struct led_classdev *cdev, 279 static void lm3642_strobe_brightness_set(struct led_classdev *cdev,
280 enum led_brightness brightness) 280 enum led_brightness brightness)
281 { 281 {
282 struct lm3642_chip_data *chip = 282 struct lm3642_chip_data *chip =
283 container_of(cdev, struct lm3642_chip_data, cdev_flash); 283 container_of(cdev, struct lm3642_chip_data, cdev_flash);
284 284
285 chip->br_flash = brightness; 285 chip->br_flash = brightness;
286 schedule_work(&chip->work_flash); 286 schedule_work(&chip->work_flash);
287 } 287 }
288 288
289 /* indicator */ 289 /* indicator */
290 static void lm3642_deferred_indicator_brightness_set(struct work_struct *work) 290 static void lm3642_deferred_indicator_brightness_set(struct work_struct *work)
291 { 291 {
292 struct lm3642_chip_data *chip = 292 struct lm3642_chip_data *chip =
293 container_of(work, struct lm3642_chip_data, work_indicator); 293 container_of(work, struct lm3642_chip_data, work_indicator);
294 294
295 mutex_lock(&chip->lock); 295 mutex_lock(&chip->lock);
296 lm3642_control(chip, chip->br_indicator, MODES_INDIC); 296 lm3642_control(chip, chip->br_indicator, MODES_INDIC);
297 mutex_unlock(&chip->lock); 297 mutex_unlock(&chip->lock);
298 } 298 }
299 299
300 static void lm3642_indicator_brightness_set(struct led_classdev *cdev, 300 static void lm3642_indicator_brightness_set(struct led_classdev *cdev,
301 enum led_brightness brightness) 301 enum led_brightness brightness)
302 { 302 {
303 struct lm3642_chip_data *chip = 303 struct lm3642_chip_data *chip =
304 container_of(cdev, struct lm3642_chip_data, cdev_indicator); 304 container_of(cdev, struct lm3642_chip_data, cdev_indicator);
305 305
306 chip->br_indicator = brightness; 306 chip->br_indicator = brightness;
307 schedule_work(&chip->work_indicator); 307 schedule_work(&chip->work_indicator);
308 } 308 }
309 309
310 static const struct regmap_config lm3642_regmap = { 310 static const struct regmap_config lm3642_regmap = {
311 .reg_bits = 8, 311 .reg_bits = 8,
312 .val_bits = 8, 312 .val_bits = 8,
313 .max_register = REG_MAX, 313 .max_register = REG_MAX,
314 }; 314 };
315 315
316 static int lm3642_probe(struct i2c_client *client, 316 static int lm3642_probe(struct i2c_client *client,
317 const struct i2c_device_id *id) 317 const struct i2c_device_id *id)
318 { 318 {
319 struct lm3642_platform_data *pdata = client->dev.platform_data; 319 struct lm3642_platform_data *pdata = dev_get_platdata(&client->dev);
320 struct lm3642_chip_data *chip; 320 struct lm3642_chip_data *chip;
321 321
322 int err; 322 int err;
323 323
324 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 324 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
325 dev_err(&client->dev, "i2c functionality check fail.\n"); 325 dev_err(&client->dev, "i2c functionality check fail.\n");
326 return -EOPNOTSUPP; 326 return -EOPNOTSUPP;
327 } 327 }
328 328
329 if (pdata == NULL) { 329 if (pdata == NULL) {
330 dev_err(&client->dev, "needs Platform Data.\n"); 330 dev_err(&client->dev, "needs Platform Data.\n");
331 return -ENODATA; 331 return -ENODATA;
332 } 332 }
333 333
334 chip = devm_kzalloc(&client->dev, 334 chip = devm_kzalloc(&client->dev,
335 sizeof(struct lm3642_chip_data), GFP_KERNEL); 335 sizeof(struct lm3642_chip_data), GFP_KERNEL);
336 if (!chip) 336 if (!chip)
337 return -ENOMEM; 337 return -ENOMEM;
338 338
339 chip->dev = &client->dev; 339 chip->dev = &client->dev;
340 chip->pdata = pdata; 340 chip->pdata = pdata;
341 341
342 chip->tx_pin = pdata->tx_pin; 342 chip->tx_pin = pdata->tx_pin;
343 chip->torch_pin = pdata->torch_pin; 343 chip->torch_pin = pdata->torch_pin;
344 chip->strobe_pin = pdata->strobe_pin; 344 chip->strobe_pin = pdata->strobe_pin;
345 345
346 chip->regmap = devm_regmap_init_i2c(client, &lm3642_regmap); 346 chip->regmap = devm_regmap_init_i2c(client, &lm3642_regmap);
347 if (IS_ERR(chip->regmap)) { 347 if (IS_ERR(chip->regmap)) {
348 err = PTR_ERR(chip->regmap); 348 err = PTR_ERR(chip->regmap);
349 dev_err(&client->dev, "Failed to allocate register map: %d\n", 349 dev_err(&client->dev, "Failed to allocate register map: %d\n",
350 err); 350 err);
351 return err; 351 return err;
352 } 352 }
353 353
354 mutex_init(&chip->lock); 354 mutex_init(&chip->lock);
355 i2c_set_clientdata(client, chip); 355 i2c_set_clientdata(client, chip);
356 356
357 err = lm3642_chip_init(chip); 357 err = lm3642_chip_init(chip);
358 if (err < 0) 358 if (err < 0)
359 goto err_out; 359 goto err_out;
360 360
361 /* flash */ 361 /* flash */
362 INIT_WORK(&chip->work_flash, lm3642_deferred_strobe_brightness_set); 362 INIT_WORK(&chip->work_flash, lm3642_deferred_strobe_brightness_set);
363 chip->cdev_flash.name = "flash"; 363 chip->cdev_flash.name = "flash";
364 chip->cdev_flash.max_brightness = 16; 364 chip->cdev_flash.max_brightness = 16;
365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set; 365 chip->cdev_flash.brightness_set = lm3642_strobe_brightness_set;
366 chip->cdev_flash.default_trigger = "flash"; 366 chip->cdev_flash.default_trigger = "flash";
367 err = led_classdev_register((struct device *) 367 err = led_classdev_register((struct device *)
368 &client->dev, &chip->cdev_flash); 368 &client->dev, &chip->cdev_flash);
369 if (err < 0) { 369 if (err < 0) {
370 dev_err(chip->dev, "failed to register flash\n"); 370 dev_err(chip->dev, "failed to register flash\n");
371 goto err_out; 371 goto err_out;
372 } 372 }
373 err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin); 373 err = device_create_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
374 if (err < 0) { 374 if (err < 0) {
375 dev_err(chip->dev, "failed to create strobe-pin file\n"); 375 dev_err(chip->dev, "failed to create strobe-pin file\n");
376 goto err_create_flash_pin_file; 376 goto err_create_flash_pin_file;
377 } 377 }
378 378
379 /* torch */ 379 /* torch */
380 INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set); 380 INIT_WORK(&chip->work_torch, lm3642_deferred_torch_brightness_set);
381 chip->cdev_torch.name = "torch"; 381 chip->cdev_torch.name = "torch";
382 chip->cdev_torch.max_brightness = 8; 382 chip->cdev_torch.max_brightness = 8;
383 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set; 383 chip->cdev_torch.brightness_set = lm3642_torch_brightness_set;
384 chip->cdev_torch.default_trigger = "torch"; 384 chip->cdev_torch.default_trigger = "torch";
385 err = led_classdev_register((struct device *) 385 err = led_classdev_register((struct device *)
386 &client->dev, &chip->cdev_torch); 386 &client->dev, &chip->cdev_torch);
387 if (err < 0) { 387 if (err < 0) {
388 dev_err(chip->dev, "failed to register torch\n"); 388 dev_err(chip->dev, "failed to register torch\n");
389 goto err_create_torch_file; 389 goto err_create_torch_file;
390 } 390 }
391 err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin); 391 err = device_create_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
392 if (err < 0) { 392 if (err < 0) {
393 dev_err(chip->dev, "failed to create torch-pin file\n"); 393 dev_err(chip->dev, "failed to create torch-pin file\n");
394 goto err_create_torch_pin_file; 394 goto err_create_torch_pin_file;
395 } 395 }
396 396
397 /* indicator */ 397 /* indicator */
398 INIT_WORK(&chip->work_indicator, 398 INIT_WORK(&chip->work_indicator,
399 lm3642_deferred_indicator_brightness_set); 399 lm3642_deferred_indicator_brightness_set);
400 chip->cdev_indicator.name = "indicator"; 400 chip->cdev_indicator.name = "indicator";
401 chip->cdev_indicator.max_brightness = 8; 401 chip->cdev_indicator.max_brightness = 8;
402 chip->cdev_indicator.brightness_set = lm3642_indicator_brightness_set; 402 chip->cdev_indicator.brightness_set = lm3642_indicator_brightness_set;
403 err = led_classdev_register((struct device *) 403 err = led_classdev_register((struct device *)
404 &client->dev, &chip->cdev_indicator); 404 &client->dev, &chip->cdev_indicator);
405 if (err < 0) { 405 if (err < 0) {
406 dev_err(chip->dev, "failed to register indicator\n"); 406 dev_err(chip->dev, "failed to register indicator\n");
407 goto err_create_indicator_file; 407 goto err_create_indicator_file;
408 } 408 }
409 409
410 dev_info(&client->dev, "LM3642 is initialized\n"); 410 dev_info(&client->dev, "LM3642 is initialized\n");
411 return 0; 411 return 0;
412 412
413 err_create_indicator_file: 413 err_create_indicator_file:
414 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin); 414 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
415 err_create_torch_pin_file: 415 err_create_torch_pin_file:
416 led_classdev_unregister(&chip->cdev_torch); 416 led_classdev_unregister(&chip->cdev_torch);
417 err_create_torch_file: 417 err_create_torch_file:
418 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin); 418 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
419 err_create_flash_pin_file: 419 err_create_flash_pin_file:
420 led_classdev_unregister(&chip->cdev_flash); 420 led_classdev_unregister(&chip->cdev_flash);
421 err_out: 421 err_out:
422 return err; 422 return err;
423 } 423 }
424 424
425 static int lm3642_remove(struct i2c_client *client) 425 static int lm3642_remove(struct i2c_client *client)
426 { 426 {
427 struct lm3642_chip_data *chip = i2c_get_clientdata(client); 427 struct lm3642_chip_data *chip = i2c_get_clientdata(client);
428 428
429 led_classdev_unregister(&chip->cdev_indicator); 429 led_classdev_unregister(&chip->cdev_indicator);
430 flush_work(&chip->work_indicator); 430 flush_work(&chip->work_indicator);
431 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin); 431 device_remove_file(chip->cdev_torch.dev, &dev_attr_torch_pin);
432 led_classdev_unregister(&chip->cdev_torch); 432 led_classdev_unregister(&chip->cdev_torch);
433 flush_work(&chip->work_torch); 433 flush_work(&chip->work_torch);
434 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin); 434 device_remove_file(chip->cdev_flash.dev, &dev_attr_strobe_pin);
435 led_classdev_unregister(&chip->cdev_flash); 435 led_classdev_unregister(&chip->cdev_flash);
436 flush_work(&chip->work_flash); 436 flush_work(&chip->work_flash);
437 regmap_write(chip->regmap, REG_ENABLE, 0); 437 regmap_write(chip->regmap, REG_ENABLE, 0);
438 return 0; 438 return 0;
439 } 439 }
440 440
441 static const struct i2c_device_id lm3642_id[] = { 441 static const struct i2c_device_id lm3642_id[] = {
442 {LM3642_NAME, 0}, 442 {LM3642_NAME, 0},
443 {} 443 {}
444 }; 444 };
445 445
446 MODULE_DEVICE_TABLE(i2c, lm3642_id); 446 MODULE_DEVICE_TABLE(i2c, lm3642_id);
447 447
448 static struct i2c_driver lm3642_i2c_driver = { 448 static struct i2c_driver lm3642_i2c_driver = {
449 .driver = { 449 .driver = {
450 .name = LM3642_NAME, 450 .name = LM3642_NAME,
451 .owner = THIS_MODULE, 451 .owner = THIS_MODULE,
452 .pm = NULL, 452 .pm = NULL,
453 }, 453 },
454 .probe = lm3642_probe, 454 .probe = lm3642_probe,
455 .remove = lm3642_remove, 455 .remove = lm3642_remove,
456 .id_table = lm3642_id, 456 .id_table = lm3642_id,
457 }; 457 };
458 458
459 module_i2c_driver(lm3642_i2c_driver); 459 module_i2c_driver(lm3642_i2c_driver);
460 460
461 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3642"); 461 MODULE_DESCRIPTION("Texas Instruments Flash Lighting driver for LM3642");
462 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); 462 MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>");
463 MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>"); 463 MODULE_AUTHOR("G.Shark Jeong <gshark.jeong@gmail.com>");
464 MODULE_LICENSE("GPL v2"); 464 MODULE_LICENSE("GPL v2");
465 465
drivers/leds/leds-lp3944.c
1 /* 1 /*
2 * leds-lp3944.c - driver for National Semiconductor LP3944 Funlight Chip 2 * leds-lp3944.c - driver for National Semiconductor LP3944 Funlight Chip
3 * 3 *
4 * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 */ 10 */
11 11
12 /* 12 /*
13 * I2C driver for National Semiconductor LP3944 Funlight Chip 13 * I2C driver for National Semiconductor LP3944 Funlight Chip
14 * http://www.national.com/pf/LP/LP3944.html 14 * http://www.national.com/pf/LP/LP3944.html
15 * 15 *
16 * This helper chip can drive up to 8 leds, with two programmable DIM modes; 16 * This helper chip can drive up to 8 leds, with two programmable DIM modes;
17 * it could even be used as a gpio expander but this driver assumes it is used 17 * it could even be used as a gpio expander but this driver assumes it is used
18 * as a led controller. 18 * as a led controller.
19 * 19 *
20 * The DIM modes are used to set _blink_ patterns for leds, the pattern is 20 * The DIM modes are used to set _blink_ patterns for leds, the pattern is
21 * specified supplying two parameters: 21 * specified supplying two parameters:
22 * - period: from 0s to 1.6s 22 * - period: from 0s to 1.6s
23 * - duty cycle: percentage of the period the led is on, from 0 to 100 23 * - duty cycle: percentage of the period the led is on, from 0 to 100
24 * 24 *
25 * LP3944 can be found on Motorola A910 smartphone, where it drives the rgb 25 * LP3944 can be found on Motorola A910 smartphone, where it drives the rgb
26 * leds, the camera flash light and the displays backlights. 26 * leds, the camera flash light and the displays backlights.
27 */ 27 */
28 28
29 #include <linux/module.h> 29 #include <linux/module.h>
30 #include <linux/i2c.h> 30 #include <linux/i2c.h>
31 #include <linux/slab.h> 31 #include <linux/slab.h>
32 #include <linux/leds.h> 32 #include <linux/leds.h>
33 #include <linux/mutex.h> 33 #include <linux/mutex.h>
34 #include <linux/workqueue.h> 34 #include <linux/workqueue.h>
35 #include <linux/leds-lp3944.h> 35 #include <linux/leds-lp3944.h>
36 36
37 /* Read Only Registers */ 37 /* Read Only Registers */
38 #define LP3944_REG_INPUT1 0x00 /* LEDs 0-7 InputRegister (Read Only) */ 38 #define LP3944_REG_INPUT1 0x00 /* LEDs 0-7 InputRegister (Read Only) */
39 #define LP3944_REG_REGISTER1 0x01 /* None (Read Only) */ 39 #define LP3944_REG_REGISTER1 0x01 /* None (Read Only) */
40 40
41 #define LP3944_REG_PSC0 0x02 /* Frequency Prescaler 0 (R/W) */ 41 #define LP3944_REG_PSC0 0x02 /* Frequency Prescaler 0 (R/W) */
42 #define LP3944_REG_PWM0 0x03 /* PWM Register 0 (R/W) */ 42 #define LP3944_REG_PWM0 0x03 /* PWM Register 0 (R/W) */
43 #define LP3944_REG_PSC1 0x04 /* Frequency Prescaler 1 (R/W) */ 43 #define LP3944_REG_PSC1 0x04 /* Frequency Prescaler 1 (R/W) */
44 #define LP3944_REG_PWM1 0x05 /* PWM Register 1 (R/W) */ 44 #define LP3944_REG_PWM1 0x05 /* PWM Register 1 (R/W) */
45 #define LP3944_REG_LS0 0x06 /* LEDs 0-3 Selector (R/W) */ 45 #define LP3944_REG_LS0 0x06 /* LEDs 0-3 Selector (R/W) */
46 #define LP3944_REG_LS1 0x07 /* LEDs 4-7 Selector (R/W) */ 46 #define LP3944_REG_LS1 0x07 /* LEDs 4-7 Selector (R/W) */
47 47
48 /* These registers are not used to control leds in LP3944, they can store 48 /* These registers are not used to control leds in LP3944, they can store
49 * arbitrary values which the chip will ignore. 49 * arbitrary values which the chip will ignore.
50 */ 50 */
51 #define LP3944_REG_REGISTER8 0x08 51 #define LP3944_REG_REGISTER8 0x08
52 #define LP3944_REG_REGISTER9 0x09 52 #define LP3944_REG_REGISTER9 0x09
53 53
54 #define LP3944_DIM0 0 54 #define LP3944_DIM0 0
55 #define LP3944_DIM1 1 55 #define LP3944_DIM1 1
56 56
57 /* period in ms */ 57 /* period in ms */
58 #define LP3944_PERIOD_MIN 0 58 #define LP3944_PERIOD_MIN 0
59 #define LP3944_PERIOD_MAX 1600 59 #define LP3944_PERIOD_MAX 1600
60 60
61 /* duty cycle is a percentage */ 61 /* duty cycle is a percentage */
62 #define LP3944_DUTY_CYCLE_MIN 0 62 #define LP3944_DUTY_CYCLE_MIN 0
63 #define LP3944_DUTY_CYCLE_MAX 100 63 #define LP3944_DUTY_CYCLE_MAX 100
64 64
65 #define ldev_to_led(c) container_of(c, struct lp3944_led_data, ldev) 65 #define ldev_to_led(c) container_of(c, struct lp3944_led_data, ldev)
66 66
67 /* Saved data */ 67 /* Saved data */
68 struct lp3944_led_data { 68 struct lp3944_led_data {
69 u8 id; 69 u8 id;
70 enum lp3944_type type; 70 enum lp3944_type type;
71 enum lp3944_status status; 71 enum lp3944_status status;
72 struct led_classdev ldev; 72 struct led_classdev ldev;
73 struct i2c_client *client; 73 struct i2c_client *client;
74 struct work_struct work; 74 struct work_struct work;
75 }; 75 };
76 76
77 struct lp3944_data { 77 struct lp3944_data {
78 struct mutex lock; 78 struct mutex lock;
79 struct i2c_client *client; 79 struct i2c_client *client;
80 struct lp3944_led_data leds[LP3944_LEDS_MAX]; 80 struct lp3944_led_data leds[LP3944_LEDS_MAX];
81 }; 81 };
82 82
83 static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value) 83 static int lp3944_reg_read(struct i2c_client *client, u8 reg, u8 *value)
84 { 84 {
85 int tmp; 85 int tmp;
86 86
87 tmp = i2c_smbus_read_byte_data(client, reg); 87 tmp = i2c_smbus_read_byte_data(client, reg);
88 if (tmp < 0) 88 if (tmp < 0)
89 return tmp; 89 return tmp;
90 90
91 *value = tmp; 91 *value = tmp;
92 92
93 return 0; 93 return 0;
94 } 94 }
95 95
96 static int lp3944_reg_write(struct i2c_client *client, u8 reg, u8 value) 96 static int lp3944_reg_write(struct i2c_client *client, u8 reg, u8 value)
97 { 97 {
98 return i2c_smbus_write_byte_data(client, reg, value); 98 return i2c_smbus_write_byte_data(client, reg, value);
99 } 99 }
100 100
101 /** 101 /**
102 * Set the period for DIM status 102 * Set the period for DIM status
103 * 103 *
104 * @client: the i2c client 104 * @client: the i2c client
105 * @dim: either LP3944_DIM0 or LP3944_DIM1 105 * @dim: either LP3944_DIM0 or LP3944_DIM1
106 * @period: period of a blink, that is a on/off cycle, expressed in ms. 106 * @period: period of a blink, that is a on/off cycle, expressed in ms.
107 */ 107 */
108 static int lp3944_dim_set_period(struct i2c_client *client, u8 dim, u16 period) 108 static int lp3944_dim_set_period(struct i2c_client *client, u8 dim, u16 period)
109 { 109 {
110 u8 psc_reg; 110 u8 psc_reg;
111 u8 psc_value; 111 u8 psc_value;
112 int err; 112 int err;
113 113
114 if (dim == LP3944_DIM0) 114 if (dim == LP3944_DIM0)
115 psc_reg = LP3944_REG_PSC0; 115 psc_reg = LP3944_REG_PSC0;
116 else if (dim == LP3944_DIM1) 116 else if (dim == LP3944_DIM1)
117 psc_reg = LP3944_REG_PSC1; 117 psc_reg = LP3944_REG_PSC1;
118 else 118 else
119 return -EINVAL; 119 return -EINVAL;
120 120
121 /* Convert period to Prescaler value */ 121 /* Convert period to Prescaler value */
122 if (period > LP3944_PERIOD_MAX) 122 if (period > LP3944_PERIOD_MAX)
123 return -EINVAL; 123 return -EINVAL;
124 124
125 psc_value = (period * 255) / LP3944_PERIOD_MAX; 125 psc_value = (period * 255) / LP3944_PERIOD_MAX;
126 126
127 err = lp3944_reg_write(client, psc_reg, psc_value); 127 err = lp3944_reg_write(client, psc_reg, psc_value);
128 128
129 return err; 129 return err;
130 } 130 }
131 131
132 /** 132 /**
133 * Set the duty cycle for DIM status 133 * Set the duty cycle for DIM status
134 * 134 *
135 * @client: the i2c client 135 * @client: the i2c client
136 * @dim: either LP3944_DIM0 or LP3944_DIM1 136 * @dim: either LP3944_DIM0 or LP3944_DIM1
137 * @duty_cycle: percentage of a period during which a led is ON 137 * @duty_cycle: percentage of a period during which a led is ON
138 */ 138 */
139 static int lp3944_dim_set_dutycycle(struct i2c_client *client, u8 dim, 139 static int lp3944_dim_set_dutycycle(struct i2c_client *client, u8 dim,
140 u8 duty_cycle) 140 u8 duty_cycle)
141 { 141 {
142 u8 pwm_reg; 142 u8 pwm_reg;
143 u8 pwm_value; 143 u8 pwm_value;
144 int err; 144 int err;
145 145
146 if (dim == LP3944_DIM0) 146 if (dim == LP3944_DIM0)
147 pwm_reg = LP3944_REG_PWM0; 147 pwm_reg = LP3944_REG_PWM0;
148 else if (dim == LP3944_DIM1) 148 else if (dim == LP3944_DIM1)
149 pwm_reg = LP3944_REG_PWM1; 149 pwm_reg = LP3944_REG_PWM1;
150 else 150 else
151 return -EINVAL; 151 return -EINVAL;
152 152
153 /* Convert duty cycle to PWM value */ 153 /* Convert duty cycle to PWM value */
154 if (duty_cycle > LP3944_DUTY_CYCLE_MAX) 154 if (duty_cycle > LP3944_DUTY_CYCLE_MAX)
155 return -EINVAL; 155 return -EINVAL;
156 156
157 pwm_value = (duty_cycle * 255) / LP3944_DUTY_CYCLE_MAX; 157 pwm_value = (duty_cycle * 255) / LP3944_DUTY_CYCLE_MAX;
158 158
159 err = lp3944_reg_write(client, pwm_reg, pwm_value); 159 err = lp3944_reg_write(client, pwm_reg, pwm_value);
160 160
161 return err; 161 return err;
162 } 162 }
163 163
164 /** 164 /**
165 * Set the led status 165 * Set the led status
166 * 166 *
167 * @led: a lp3944_led_data structure 167 * @led: a lp3944_led_data structure
168 * @status: one of LP3944_LED_STATUS_OFF 168 * @status: one of LP3944_LED_STATUS_OFF
169 * LP3944_LED_STATUS_ON 169 * LP3944_LED_STATUS_ON
170 * LP3944_LED_STATUS_DIM0 170 * LP3944_LED_STATUS_DIM0
171 * LP3944_LED_STATUS_DIM1 171 * LP3944_LED_STATUS_DIM1
172 */ 172 */
173 static int lp3944_led_set(struct lp3944_led_data *led, u8 status) 173 static int lp3944_led_set(struct lp3944_led_data *led, u8 status)
174 { 174 {
175 struct lp3944_data *data = i2c_get_clientdata(led->client); 175 struct lp3944_data *data = i2c_get_clientdata(led->client);
176 u8 id = led->id; 176 u8 id = led->id;
177 u8 reg; 177 u8 reg;
178 u8 val = 0; 178 u8 val = 0;
179 int err; 179 int err;
180 180
181 dev_dbg(&led->client->dev, "%s: %s, status before normalization:%d\n", 181 dev_dbg(&led->client->dev, "%s: %s, status before normalization:%d\n",
182 __func__, led->ldev.name, status); 182 __func__, led->ldev.name, status);
183 183
184 switch (id) { 184 switch (id) {
185 case LP3944_LED0: 185 case LP3944_LED0:
186 case LP3944_LED1: 186 case LP3944_LED1:
187 case LP3944_LED2: 187 case LP3944_LED2:
188 case LP3944_LED3: 188 case LP3944_LED3:
189 reg = LP3944_REG_LS0; 189 reg = LP3944_REG_LS0;
190 break; 190 break;
191 case LP3944_LED4: 191 case LP3944_LED4:
192 case LP3944_LED5: 192 case LP3944_LED5:
193 case LP3944_LED6: 193 case LP3944_LED6:
194 case LP3944_LED7: 194 case LP3944_LED7:
195 id -= LP3944_LED4; 195 id -= LP3944_LED4;
196 reg = LP3944_REG_LS1; 196 reg = LP3944_REG_LS1;
197 break; 197 break;
198 default: 198 default:
199 return -EINVAL; 199 return -EINVAL;
200 } 200 }
201 201
202 if (status > LP3944_LED_STATUS_DIM1) 202 if (status > LP3944_LED_STATUS_DIM1)
203 return -EINVAL; 203 return -EINVAL;
204 204
205 /* invert only 0 and 1, leave unchanged the other values, 205 /* invert only 0 and 1, leave unchanged the other values,
206 * remember we are abusing status to set blink patterns 206 * remember we are abusing status to set blink patterns
207 */ 207 */
208 if (led->type == LP3944_LED_TYPE_LED_INVERTED && status < 2) 208 if (led->type == LP3944_LED_TYPE_LED_INVERTED && status < 2)
209 status = 1 - status; 209 status = 1 - status;
210 210
211 mutex_lock(&data->lock); 211 mutex_lock(&data->lock);
212 lp3944_reg_read(led->client, reg, &val); 212 lp3944_reg_read(led->client, reg, &val);
213 213
214 val &= ~(LP3944_LED_STATUS_MASK << (id << 1)); 214 val &= ~(LP3944_LED_STATUS_MASK << (id << 1));
215 val |= (status << (id << 1)); 215 val |= (status << (id << 1));
216 216
217 dev_dbg(&led->client->dev, "%s: %s, reg:%d id:%d status:%d val:%#x\n", 217 dev_dbg(&led->client->dev, "%s: %s, reg:%d id:%d status:%d val:%#x\n",
218 __func__, led->ldev.name, reg, id, status, val); 218 __func__, led->ldev.name, reg, id, status, val);
219 219
220 /* set led status */ 220 /* set led status */
221 err = lp3944_reg_write(led->client, reg, val); 221 err = lp3944_reg_write(led->client, reg, val);
222 mutex_unlock(&data->lock); 222 mutex_unlock(&data->lock);
223 223
224 return err; 224 return err;
225 } 225 }
226 226
227 static int lp3944_led_set_blink(struct led_classdev *led_cdev, 227 static int lp3944_led_set_blink(struct led_classdev *led_cdev,
228 unsigned long *delay_on, 228 unsigned long *delay_on,
229 unsigned long *delay_off) 229 unsigned long *delay_off)
230 { 230 {
231 struct lp3944_led_data *led = ldev_to_led(led_cdev); 231 struct lp3944_led_data *led = ldev_to_led(led_cdev);
232 u16 period; 232 u16 period;
233 u8 duty_cycle; 233 u8 duty_cycle;
234 int err; 234 int err;
235 235
236 /* units are in ms */ 236 /* units are in ms */
237 if (*delay_on + *delay_off > LP3944_PERIOD_MAX) 237 if (*delay_on + *delay_off > LP3944_PERIOD_MAX)
238 return -EINVAL; 238 return -EINVAL;
239 239
240 if (*delay_on == 0 && *delay_off == 0) { 240 if (*delay_on == 0 && *delay_off == 0) {
241 /* Special case: the leds subsystem requires a default user 241 /* Special case: the leds subsystem requires a default user
242 * friendly blink pattern for the LED. Let's blink the led 242 * friendly blink pattern for the LED. Let's blink the led
243 * slowly (1Hz). 243 * slowly (1Hz).
244 */ 244 */
245 *delay_on = 500; 245 *delay_on = 500;
246 *delay_off = 500; 246 *delay_off = 500;
247 } 247 }
248 248
249 period = (*delay_on) + (*delay_off); 249 period = (*delay_on) + (*delay_off);
250 250
251 /* duty_cycle is the percentage of period during which the led is ON */ 251 /* duty_cycle is the percentage of period during which the led is ON */
252 duty_cycle = 100 * (*delay_on) / period; 252 duty_cycle = 100 * (*delay_on) / period;
253 253
254 /* invert duty cycle for inverted leds, this has the same effect of 254 /* invert duty cycle for inverted leds, this has the same effect of
255 * swapping delay_on and delay_off 255 * swapping delay_on and delay_off
256 */ 256 */
257 if (led->type == LP3944_LED_TYPE_LED_INVERTED) 257 if (led->type == LP3944_LED_TYPE_LED_INVERTED)
258 duty_cycle = 100 - duty_cycle; 258 duty_cycle = 100 - duty_cycle;
259 259
260 /* NOTE: using always the first DIM mode, this means that all leds 260 /* NOTE: using always the first DIM mode, this means that all leds
261 * will have the same blinking pattern. 261 * will have the same blinking pattern.
262 * 262 *
263 * We could find a way later to have two leds blinking in hardware 263 * We could find a way later to have two leds blinking in hardware
264 * with different patterns at the same time, falling back to software 264 * with different patterns at the same time, falling back to software
265 * control for the other ones. 265 * control for the other ones.
266 */ 266 */
267 err = lp3944_dim_set_period(led->client, LP3944_DIM0, period); 267 err = lp3944_dim_set_period(led->client, LP3944_DIM0, period);
268 if (err) 268 if (err)
269 return err; 269 return err;
270 270
271 err = lp3944_dim_set_dutycycle(led->client, LP3944_DIM0, duty_cycle); 271 err = lp3944_dim_set_dutycycle(led->client, LP3944_DIM0, duty_cycle);
272 if (err) 272 if (err)
273 return err; 273 return err;
274 274
275 dev_dbg(&led->client->dev, "%s: OK hardware accelerated blink!\n", 275 dev_dbg(&led->client->dev, "%s: OK hardware accelerated blink!\n",
276 __func__); 276 __func__);
277 277
278 led->status = LP3944_LED_STATUS_DIM0; 278 led->status = LP3944_LED_STATUS_DIM0;
279 schedule_work(&led->work); 279 schedule_work(&led->work);
280 280
281 return 0; 281 return 0;
282 } 282 }
283 283
284 static void lp3944_led_set_brightness(struct led_classdev *led_cdev, 284 static void lp3944_led_set_brightness(struct led_classdev *led_cdev,
285 enum led_brightness brightness) 285 enum led_brightness brightness)
286 { 286 {
287 struct lp3944_led_data *led = ldev_to_led(led_cdev); 287 struct lp3944_led_data *led = ldev_to_led(led_cdev);
288 288
289 dev_dbg(&led->client->dev, "%s: %s, %d\n", 289 dev_dbg(&led->client->dev, "%s: %s, %d\n",
290 __func__, led_cdev->name, brightness); 290 __func__, led_cdev->name, brightness);
291 291
292 led->status = brightness; 292 led->status = brightness;
293 schedule_work(&led->work); 293 schedule_work(&led->work);
294 } 294 }
295 295
296 static void lp3944_led_work(struct work_struct *work) 296 static void lp3944_led_work(struct work_struct *work)
297 { 297 {
298 struct lp3944_led_data *led; 298 struct lp3944_led_data *led;
299 299
300 led = container_of(work, struct lp3944_led_data, work); 300 led = container_of(work, struct lp3944_led_data, work);
301 lp3944_led_set(led, led->status); 301 lp3944_led_set(led, led->status);
302 } 302 }
303 303
304 static int lp3944_configure(struct i2c_client *client, 304 static int lp3944_configure(struct i2c_client *client,
305 struct lp3944_data *data, 305 struct lp3944_data *data,
306 struct lp3944_platform_data *pdata) 306 struct lp3944_platform_data *pdata)
307 { 307 {
308 int i, err = 0; 308 int i, err = 0;
309 309
310 for (i = 0; i < pdata->leds_size; i++) { 310 for (i = 0; i < pdata->leds_size; i++) {
311 struct lp3944_led *pled = &pdata->leds[i]; 311 struct lp3944_led *pled = &pdata->leds[i];
312 struct lp3944_led_data *led = &data->leds[i]; 312 struct lp3944_led_data *led = &data->leds[i];
313 led->client = client; 313 led->client = client;
314 led->id = i; 314 led->id = i;
315 315
316 switch (pled->type) { 316 switch (pled->type) {
317 317
318 case LP3944_LED_TYPE_LED: 318 case LP3944_LED_TYPE_LED:
319 case LP3944_LED_TYPE_LED_INVERTED: 319 case LP3944_LED_TYPE_LED_INVERTED:
320 led->type = pled->type; 320 led->type = pled->type;
321 led->status = pled->status; 321 led->status = pled->status;
322 led->ldev.name = pled->name; 322 led->ldev.name = pled->name;
323 led->ldev.max_brightness = 1; 323 led->ldev.max_brightness = 1;
324 led->ldev.brightness_set = lp3944_led_set_brightness; 324 led->ldev.brightness_set = lp3944_led_set_brightness;
325 led->ldev.blink_set = lp3944_led_set_blink; 325 led->ldev.blink_set = lp3944_led_set_blink;
326 led->ldev.flags = LED_CORE_SUSPENDRESUME; 326 led->ldev.flags = LED_CORE_SUSPENDRESUME;
327 327
328 INIT_WORK(&led->work, lp3944_led_work); 328 INIT_WORK(&led->work, lp3944_led_work);
329 err = led_classdev_register(&client->dev, &led->ldev); 329 err = led_classdev_register(&client->dev, &led->ldev);
330 if (err < 0) { 330 if (err < 0) {
331 dev_err(&client->dev, 331 dev_err(&client->dev,
332 "couldn't register LED %s\n", 332 "couldn't register LED %s\n",
333 led->ldev.name); 333 led->ldev.name);
334 goto exit; 334 goto exit;
335 } 335 }
336 336
337 /* to expose the default value to userspace */ 337 /* to expose the default value to userspace */
338 led->ldev.brightness = led->status; 338 led->ldev.brightness = led->status;
339 339
340 /* Set the default led status */ 340 /* Set the default led status */
341 err = lp3944_led_set(led, led->status); 341 err = lp3944_led_set(led, led->status);
342 if (err < 0) { 342 if (err < 0) {
343 dev_err(&client->dev, 343 dev_err(&client->dev,
344 "%s couldn't set STATUS %d\n", 344 "%s couldn't set STATUS %d\n",
345 led->ldev.name, led->status); 345 led->ldev.name, led->status);
346 goto exit; 346 goto exit;
347 } 347 }
348 break; 348 break;
349 349
350 case LP3944_LED_TYPE_NONE: 350 case LP3944_LED_TYPE_NONE:
351 default: 351 default:
352 break; 352 break;
353 353
354 } 354 }
355 } 355 }
356 return 0; 356 return 0;
357 357
358 exit: 358 exit:
359 if (i > 0) 359 if (i > 0)
360 for (i = i - 1; i >= 0; i--) 360 for (i = i - 1; i >= 0; i--)
361 switch (pdata->leds[i].type) { 361 switch (pdata->leds[i].type) {
362 362
363 case LP3944_LED_TYPE_LED: 363 case LP3944_LED_TYPE_LED:
364 case LP3944_LED_TYPE_LED_INVERTED: 364 case LP3944_LED_TYPE_LED_INVERTED:
365 led_classdev_unregister(&data->leds[i].ldev); 365 led_classdev_unregister(&data->leds[i].ldev);
366 cancel_work_sync(&data->leds[i].work); 366 cancel_work_sync(&data->leds[i].work);
367 break; 367 break;
368 368
369 case LP3944_LED_TYPE_NONE: 369 case LP3944_LED_TYPE_NONE:
370 default: 370 default:
371 break; 371 break;
372 } 372 }
373 373
374 return err; 374 return err;
375 } 375 }
376 376
377 static int lp3944_probe(struct i2c_client *client, 377 static int lp3944_probe(struct i2c_client *client,
378 const struct i2c_device_id *id) 378 const struct i2c_device_id *id)
379 { 379 {
380 struct lp3944_platform_data *lp3944_pdata = client->dev.platform_data; 380 struct lp3944_platform_data *lp3944_pdata =
381 dev_get_platdata(&client->dev);
381 struct lp3944_data *data; 382 struct lp3944_data *data;
382 int err; 383 int err;
383 384
384 if (lp3944_pdata == NULL) { 385 if (lp3944_pdata == NULL) {
385 dev_err(&client->dev, "no platform data\n"); 386 dev_err(&client->dev, "no platform data\n");
386 return -EINVAL; 387 return -EINVAL;
387 } 388 }
388 389
389 /* Let's see whether this adapter can support what we need. */ 390 /* Let's see whether this adapter can support what we need. */
390 if (!i2c_check_functionality(client->adapter, 391 if (!i2c_check_functionality(client->adapter,
391 I2C_FUNC_SMBUS_BYTE_DATA)) { 392 I2C_FUNC_SMBUS_BYTE_DATA)) {
392 dev_err(&client->dev, "insufficient functionality!\n"); 393 dev_err(&client->dev, "insufficient functionality!\n");
393 return -ENODEV; 394 return -ENODEV;
394 } 395 }
395 396
396 data = devm_kzalloc(&client->dev, sizeof(struct lp3944_data), 397 data = devm_kzalloc(&client->dev, sizeof(struct lp3944_data),
397 GFP_KERNEL); 398 GFP_KERNEL);
398 if (!data) 399 if (!data)
399 return -ENOMEM; 400 return -ENOMEM;
400 401
401 data->client = client; 402 data->client = client;
402 i2c_set_clientdata(client, data); 403 i2c_set_clientdata(client, data);
403 404
404 mutex_init(&data->lock); 405 mutex_init(&data->lock);
405 406
406 err = lp3944_configure(client, data, lp3944_pdata); 407 err = lp3944_configure(client, data, lp3944_pdata);
407 if (err < 0) 408 if (err < 0)
408 return err; 409 return err;
409 410
410 dev_info(&client->dev, "lp3944 enabled\n"); 411 dev_info(&client->dev, "lp3944 enabled\n");
411 return 0; 412 return 0;
412 } 413 }
413 414
414 static int lp3944_remove(struct i2c_client *client) 415 static int lp3944_remove(struct i2c_client *client)
415 { 416 {
416 struct lp3944_platform_data *pdata = client->dev.platform_data; 417 struct lp3944_platform_data *pdata = dev_get_platdata(&client->dev);
417 struct lp3944_data *data = i2c_get_clientdata(client); 418 struct lp3944_data *data = i2c_get_clientdata(client);
418 int i; 419 int i;
419 420
420 for (i = 0; i < pdata->leds_size; i++) 421 for (i = 0; i < pdata->leds_size; i++)
421 switch (data->leds[i].type) { 422 switch (data->leds[i].type) {
422 case LP3944_LED_TYPE_LED: 423 case LP3944_LED_TYPE_LED:
423 case LP3944_LED_TYPE_LED_INVERTED: 424 case LP3944_LED_TYPE_LED_INVERTED:
424 led_classdev_unregister(&data->leds[i].ldev); 425 led_classdev_unregister(&data->leds[i].ldev);
425 cancel_work_sync(&data->leds[i].work); 426 cancel_work_sync(&data->leds[i].work);
426 break; 427 break;
427 428
428 case LP3944_LED_TYPE_NONE: 429 case LP3944_LED_TYPE_NONE:
429 default: 430 default:
430 break; 431 break;
431 } 432 }
432 433
433 return 0; 434 return 0;
434 } 435 }
435 436
436 /* lp3944 i2c driver struct */ 437 /* lp3944 i2c driver struct */
437 static const struct i2c_device_id lp3944_id[] = { 438 static const struct i2c_device_id lp3944_id[] = {
438 {"lp3944", 0}, 439 {"lp3944", 0},
439 {} 440 {}
440 }; 441 };
441 442
442 MODULE_DEVICE_TABLE(i2c, lp3944_id); 443 MODULE_DEVICE_TABLE(i2c, lp3944_id);
443 444
444 static struct i2c_driver lp3944_driver = { 445 static struct i2c_driver lp3944_driver = {
445 .driver = { 446 .driver = {
446 .name = "lp3944", 447 .name = "lp3944",
447 }, 448 },
448 .probe = lp3944_probe, 449 .probe = lp3944_probe,
449 .remove = lp3944_remove, 450 .remove = lp3944_remove,
450 .id_table = lp3944_id, 451 .id_table = lp3944_id,
451 }; 452 };
452 453
453 module_i2c_driver(lp3944_driver); 454 module_i2c_driver(lp3944_driver);
454 455
455 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 456 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
456 MODULE_DESCRIPTION("LP3944 Fun Light Chip"); 457 MODULE_DESCRIPTION("LP3944 Fun Light Chip");
457 MODULE_LICENSE("GPL"); 458 MODULE_LICENSE("GPL");
458 459
drivers/leds/leds-lp5521.c
1 /* 1 /*
2 * LP5521 LED chip driver. 2 * LP5521 LED chip driver.
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2010 Nokia Corporation
5 * Copyright (C) 2012 Texas Instruments 5 * Copyright (C) 2012 Texas Instruments
6 * 6 *
7 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> 7 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
8 * Milo(Woogyom) Kim <milo.kim@ti.com> 8 * Milo(Woogyom) Kim <milo.kim@ti.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation. 12 * version 2 as published by the Free Software Foundation.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, but 14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. 17 * General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA 22 * 02110-1301 USA
23 */ 23 */
24 24
25 #include <linux/delay.h> 25 #include <linux/delay.h>
26 #include <linux/firmware.h> 26 #include <linux/firmware.h>
27 #include <linux/i2c.h> 27 #include <linux/i2c.h>
28 #include <linux/init.h> 28 #include <linux/init.h>
29 #include <linux/leds.h> 29 #include <linux/leds.h>
30 #include <linux/module.h> 30 #include <linux/module.h>
31 #include <linux/mutex.h> 31 #include <linux/mutex.h>
32 #include <linux/platform_data/leds-lp55xx.h> 32 #include <linux/platform_data/leds-lp55xx.h>
33 #include <linux/slab.h> 33 #include <linux/slab.h>
34 #include <linux/of.h> 34 #include <linux/of.h>
35 35
36 #include "leds-lp55xx-common.h" 36 #include "leds-lp55xx-common.h"
37 37
38 #define LP5521_PROGRAM_LENGTH 32 38 #define LP5521_PROGRAM_LENGTH 32
39 #define LP5521_MAX_LEDS 3 39 #define LP5521_MAX_LEDS 3
40 #define LP5521_CMD_DIRECT 0x3F 40 #define LP5521_CMD_DIRECT 0x3F
41 41
42 /* Registers */ 42 /* Registers */
43 #define LP5521_REG_ENABLE 0x00 43 #define LP5521_REG_ENABLE 0x00
44 #define LP5521_REG_OP_MODE 0x01 44 #define LP5521_REG_OP_MODE 0x01
45 #define LP5521_REG_R_PWM 0x02 45 #define LP5521_REG_R_PWM 0x02
46 #define LP5521_REG_G_PWM 0x03 46 #define LP5521_REG_G_PWM 0x03
47 #define LP5521_REG_B_PWM 0x04 47 #define LP5521_REG_B_PWM 0x04
48 #define LP5521_REG_R_CURRENT 0x05 48 #define LP5521_REG_R_CURRENT 0x05
49 #define LP5521_REG_G_CURRENT 0x06 49 #define LP5521_REG_G_CURRENT 0x06
50 #define LP5521_REG_B_CURRENT 0x07 50 #define LP5521_REG_B_CURRENT 0x07
51 #define LP5521_REG_CONFIG 0x08 51 #define LP5521_REG_CONFIG 0x08
52 #define LP5521_REG_STATUS 0x0C 52 #define LP5521_REG_STATUS 0x0C
53 #define LP5521_REG_RESET 0x0D 53 #define LP5521_REG_RESET 0x0D
54 #define LP5521_REG_R_PROG_MEM 0x10 54 #define LP5521_REG_R_PROG_MEM 0x10
55 #define LP5521_REG_G_PROG_MEM 0x30 55 #define LP5521_REG_G_PROG_MEM 0x30
56 #define LP5521_REG_B_PROG_MEM 0x50 56 #define LP5521_REG_B_PROG_MEM 0x50
57 57
58 /* Base register to set LED current */ 58 /* Base register to set LED current */
59 #define LP5521_REG_LED_CURRENT_BASE LP5521_REG_R_CURRENT 59 #define LP5521_REG_LED_CURRENT_BASE LP5521_REG_R_CURRENT
60 /* Base register to set the brightness */ 60 /* Base register to set the brightness */
61 #define LP5521_REG_LED_PWM_BASE LP5521_REG_R_PWM 61 #define LP5521_REG_LED_PWM_BASE LP5521_REG_R_PWM
62 62
63 /* Bits in ENABLE register */ 63 /* Bits in ENABLE register */
64 #define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */ 64 #define LP5521_MASTER_ENABLE 0x40 /* Chip master enable */
65 #define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */ 65 #define LP5521_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */
66 #define LP5521_EXEC_RUN 0x2A 66 #define LP5521_EXEC_RUN 0x2A
67 #define LP5521_ENABLE_DEFAULT \ 67 #define LP5521_ENABLE_DEFAULT \
68 (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM) 68 (LP5521_MASTER_ENABLE | LP5521_LOGARITHMIC_PWM)
69 #define LP5521_ENABLE_RUN_PROGRAM \ 69 #define LP5521_ENABLE_RUN_PROGRAM \
70 (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN) 70 (LP5521_ENABLE_DEFAULT | LP5521_EXEC_RUN)
71 71
72 /* CONFIG register */ 72 /* CONFIG register */
73 #define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */ 73 #define LP5521_PWM_HF 0x40 /* PWM: 0 = 256Hz, 1 = 558Hz */
74 #define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */ 74 #define LP5521_PWRSAVE_EN 0x20 /* 1 = Power save mode */
75 #define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */ 75 #define LP5521_CP_MODE_OFF 0 /* Charge pump (CP) off */
76 #define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */ 76 #define LP5521_CP_MODE_BYPASS 8 /* CP forced to bypass mode */
77 #define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */ 77 #define LP5521_CP_MODE_1X5 0x10 /* CP forced to 1.5x mode */
78 #define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */ 78 #define LP5521_CP_MODE_AUTO 0x18 /* Automatic mode selection */
79 #define LP5521_R_TO_BATT 0x04 /* R out: 0 = CP, 1 = Vbat */ 79 #define LP5521_R_TO_BATT 0x04 /* R out: 0 = CP, 1 = Vbat */
80 #define LP5521_CLK_INT 0x01 /* Internal clock */ 80 #define LP5521_CLK_INT 0x01 /* Internal clock */
81 #define LP5521_DEFAULT_CFG \ 81 #define LP5521_DEFAULT_CFG \
82 (LP5521_PWM_HF | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO) 82 (LP5521_PWM_HF | LP5521_PWRSAVE_EN | LP5521_CP_MODE_AUTO)
83 83
84 /* Status */ 84 /* Status */
85 #define LP5521_EXT_CLK_USED 0x08 85 #define LP5521_EXT_CLK_USED 0x08
86 86
87 /* default R channel current register value */ 87 /* default R channel current register value */
88 #define LP5521_REG_R_CURR_DEFAULT 0xAF 88 #define LP5521_REG_R_CURR_DEFAULT 0xAF
89 89
90 /* Reset register value */ 90 /* Reset register value */
91 #define LP5521_RESET 0xFF 91 #define LP5521_RESET 0xFF
92 92
93 /* Program Memory Operations */ 93 /* Program Memory Operations */
94 #define LP5521_MODE_R_M 0x30 /* Operation Mode Register */ 94 #define LP5521_MODE_R_M 0x30 /* Operation Mode Register */
95 #define LP5521_MODE_G_M 0x0C 95 #define LP5521_MODE_G_M 0x0C
96 #define LP5521_MODE_B_M 0x03 96 #define LP5521_MODE_B_M 0x03
97 #define LP5521_LOAD_R 0x10 97 #define LP5521_LOAD_R 0x10
98 #define LP5521_LOAD_G 0x04 98 #define LP5521_LOAD_G 0x04
99 #define LP5521_LOAD_B 0x01 99 #define LP5521_LOAD_B 0x01
100 100
101 #define LP5521_R_IS_LOADING(mode) \ 101 #define LP5521_R_IS_LOADING(mode) \
102 ((mode & LP5521_MODE_R_M) == LP5521_LOAD_R) 102 ((mode & LP5521_MODE_R_M) == LP5521_LOAD_R)
103 #define LP5521_G_IS_LOADING(mode) \ 103 #define LP5521_G_IS_LOADING(mode) \
104 ((mode & LP5521_MODE_G_M) == LP5521_LOAD_G) 104 ((mode & LP5521_MODE_G_M) == LP5521_LOAD_G)
105 #define LP5521_B_IS_LOADING(mode) \ 105 #define LP5521_B_IS_LOADING(mode) \
106 ((mode & LP5521_MODE_B_M) == LP5521_LOAD_B) 106 ((mode & LP5521_MODE_B_M) == LP5521_LOAD_B)
107 107
108 #define LP5521_EXEC_R_M 0x30 /* Enable Register */ 108 #define LP5521_EXEC_R_M 0x30 /* Enable Register */
109 #define LP5521_EXEC_G_M 0x0C 109 #define LP5521_EXEC_G_M 0x0C
110 #define LP5521_EXEC_B_M 0x03 110 #define LP5521_EXEC_B_M 0x03
111 #define LP5521_EXEC_M 0x3F 111 #define LP5521_EXEC_M 0x3F
112 #define LP5521_RUN_R 0x20 112 #define LP5521_RUN_R 0x20
113 #define LP5521_RUN_G 0x08 113 #define LP5521_RUN_G 0x08
114 #define LP5521_RUN_B 0x02 114 #define LP5521_RUN_B 0x02
115 115
116 static inline void lp5521_wait_opmode_done(void) 116 static inline void lp5521_wait_opmode_done(void)
117 { 117 {
118 /* operation mode change needs to be longer than 153 us */ 118 /* operation mode change needs to be longer than 153 us */
119 usleep_range(200, 300); 119 usleep_range(200, 300);
120 } 120 }
121 121
122 static inline void lp5521_wait_enable_done(void) 122 static inline void lp5521_wait_enable_done(void)
123 { 123 {
124 /* it takes more 488 us to update ENABLE register */ 124 /* it takes more 488 us to update ENABLE register */
125 usleep_range(500, 600); 125 usleep_range(500, 600);
126 } 126 }
127 127
128 static void lp5521_set_led_current(struct lp55xx_led *led, u8 led_current) 128 static void lp5521_set_led_current(struct lp55xx_led *led, u8 led_current)
129 { 129 {
130 led->led_current = led_current; 130 led->led_current = led_current;
131 lp55xx_write(led->chip, LP5521_REG_LED_CURRENT_BASE + led->chan_nr, 131 lp55xx_write(led->chip, LP5521_REG_LED_CURRENT_BASE + led->chan_nr,
132 led_current); 132 led_current);
133 } 133 }
134 134
135 static void lp5521_load_engine(struct lp55xx_chip *chip) 135 static void lp5521_load_engine(struct lp55xx_chip *chip)
136 { 136 {
137 enum lp55xx_engine_index idx = chip->engine_idx; 137 enum lp55xx_engine_index idx = chip->engine_idx;
138 u8 mask[] = { 138 u8 mask[] = {
139 [LP55XX_ENGINE_1] = LP5521_MODE_R_M, 139 [LP55XX_ENGINE_1] = LP5521_MODE_R_M,
140 [LP55XX_ENGINE_2] = LP5521_MODE_G_M, 140 [LP55XX_ENGINE_2] = LP5521_MODE_G_M,
141 [LP55XX_ENGINE_3] = LP5521_MODE_B_M, 141 [LP55XX_ENGINE_3] = LP5521_MODE_B_M,
142 }; 142 };
143 143
144 u8 val[] = { 144 u8 val[] = {
145 [LP55XX_ENGINE_1] = LP5521_LOAD_R, 145 [LP55XX_ENGINE_1] = LP5521_LOAD_R,
146 [LP55XX_ENGINE_2] = LP5521_LOAD_G, 146 [LP55XX_ENGINE_2] = LP5521_LOAD_G,
147 [LP55XX_ENGINE_3] = LP5521_LOAD_B, 147 [LP55XX_ENGINE_3] = LP5521_LOAD_B,
148 }; 148 };
149 149
150 lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], val[idx]); 150 lp55xx_update_bits(chip, LP5521_REG_OP_MODE, mask[idx], val[idx]);
151 151
152 lp5521_wait_opmode_done(); 152 lp5521_wait_opmode_done();
153 } 153 }
154 154
155 static void lp5521_stop_engine(struct lp55xx_chip *chip) 155 static void lp5521_stop_engine(struct lp55xx_chip *chip)
156 { 156 {
157 lp55xx_write(chip, LP5521_REG_OP_MODE, 0); 157 lp55xx_write(chip, LP5521_REG_OP_MODE, 0);
158 lp5521_wait_opmode_done(); 158 lp5521_wait_opmode_done();
159 } 159 }
160 160
161 static void lp5521_run_engine(struct lp55xx_chip *chip, bool start) 161 static void lp5521_run_engine(struct lp55xx_chip *chip, bool start)
162 { 162 {
163 int ret; 163 int ret;
164 u8 mode; 164 u8 mode;
165 u8 exec; 165 u8 exec;
166 166
167 /* stop engine */ 167 /* stop engine */
168 if (!start) { 168 if (!start) {
169 lp5521_stop_engine(chip); 169 lp5521_stop_engine(chip);
170 lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); 170 lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
171 lp5521_wait_opmode_done(); 171 lp5521_wait_opmode_done();
172 return; 172 return;
173 } 173 }
174 174
175 /* 175 /*
176 * To run the engine, 176 * To run the engine,
177 * operation mode and enable register should updated at the same time 177 * operation mode and enable register should updated at the same time
178 */ 178 */
179 179
180 ret = lp55xx_read(chip, LP5521_REG_OP_MODE, &mode); 180 ret = lp55xx_read(chip, LP5521_REG_OP_MODE, &mode);
181 if (ret) 181 if (ret)
182 return; 182 return;
183 183
184 ret = lp55xx_read(chip, LP5521_REG_ENABLE, &exec); 184 ret = lp55xx_read(chip, LP5521_REG_ENABLE, &exec);
185 if (ret) 185 if (ret)
186 return; 186 return;
187 187
188 /* change operation mode to RUN only when each engine is loading */ 188 /* change operation mode to RUN only when each engine is loading */
189 if (LP5521_R_IS_LOADING(mode)) { 189 if (LP5521_R_IS_LOADING(mode)) {
190 mode = (mode & ~LP5521_MODE_R_M) | LP5521_RUN_R; 190 mode = (mode & ~LP5521_MODE_R_M) | LP5521_RUN_R;
191 exec = (exec & ~LP5521_EXEC_R_M) | LP5521_RUN_R; 191 exec = (exec & ~LP5521_EXEC_R_M) | LP5521_RUN_R;
192 } 192 }
193 193
194 if (LP5521_G_IS_LOADING(mode)) { 194 if (LP5521_G_IS_LOADING(mode)) {
195 mode = (mode & ~LP5521_MODE_G_M) | LP5521_RUN_G; 195 mode = (mode & ~LP5521_MODE_G_M) | LP5521_RUN_G;
196 exec = (exec & ~LP5521_EXEC_G_M) | LP5521_RUN_G; 196 exec = (exec & ~LP5521_EXEC_G_M) | LP5521_RUN_G;
197 } 197 }
198 198
199 if (LP5521_B_IS_LOADING(mode)) { 199 if (LP5521_B_IS_LOADING(mode)) {
200 mode = (mode & ~LP5521_MODE_B_M) | LP5521_RUN_B; 200 mode = (mode & ~LP5521_MODE_B_M) | LP5521_RUN_B;
201 exec = (exec & ~LP5521_EXEC_B_M) | LP5521_RUN_B; 201 exec = (exec & ~LP5521_EXEC_B_M) | LP5521_RUN_B;
202 } 202 }
203 203
204 lp55xx_write(chip, LP5521_REG_OP_MODE, mode); 204 lp55xx_write(chip, LP5521_REG_OP_MODE, mode);
205 lp5521_wait_opmode_done(); 205 lp5521_wait_opmode_done();
206 206
207 lp55xx_update_bits(chip, LP5521_REG_ENABLE, LP5521_EXEC_M, exec); 207 lp55xx_update_bits(chip, LP5521_REG_ENABLE, LP5521_EXEC_M, exec);
208 lp5521_wait_enable_done(); 208 lp5521_wait_enable_done();
209 } 209 }
210 210
211 static int lp5521_update_program_memory(struct lp55xx_chip *chip, 211 static int lp5521_update_program_memory(struct lp55xx_chip *chip,
212 const u8 *data, size_t size) 212 const u8 *data, size_t size)
213 { 213 {
214 enum lp55xx_engine_index idx = chip->engine_idx; 214 enum lp55xx_engine_index idx = chip->engine_idx;
215 u8 pattern[LP5521_PROGRAM_LENGTH] = {0}; 215 u8 pattern[LP5521_PROGRAM_LENGTH] = {0};
216 u8 addr[] = { 216 u8 addr[] = {
217 [LP55XX_ENGINE_1] = LP5521_REG_R_PROG_MEM, 217 [LP55XX_ENGINE_1] = LP5521_REG_R_PROG_MEM,
218 [LP55XX_ENGINE_2] = LP5521_REG_G_PROG_MEM, 218 [LP55XX_ENGINE_2] = LP5521_REG_G_PROG_MEM,
219 [LP55XX_ENGINE_3] = LP5521_REG_B_PROG_MEM, 219 [LP55XX_ENGINE_3] = LP5521_REG_B_PROG_MEM,
220 }; 220 };
221 unsigned cmd; 221 unsigned cmd;
222 char c[3]; 222 char c[3];
223 int program_size; 223 int program_size;
224 int nrchars; 224 int nrchars;
225 int offset = 0; 225 int offset = 0;
226 int ret; 226 int ret;
227 int i; 227 int i;
228 228
229 /* clear program memory before updating */ 229 /* clear program memory before updating */
230 for (i = 0; i < LP5521_PROGRAM_LENGTH; i++) 230 for (i = 0; i < LP5521_PROGRAM_LENGTH; i++)
231 lp55xx_write(chip, addr[idx] + i, 0); 231 lp55xx_write(chip, addr[idx] + i, 0);
232 232
233 i = 0; 233 i = 0;
234 while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) { 234 while ((offset < size - 1) && (i < LP5521_PROGRAM_LENGTH)) {
235 /* separate sscanfs because length is working only for %s */ 235 /* separate sscanfs because length is working only for %s */
236 ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 236 ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
237 if (ret != 1) 237 if (ret != 1)
238 goto err; 238 goto err;
239 239
240 ret = sscanf(c, "%2x", &cmd); 240 ret = sscanf(c, "%2x", &cmd);
241 if (ret != 1) 241 if (ret != 1)
242 goto err; 242 goto err;
243 243
244 pattern[i] = (u8)cmd; 244 pattern[i] = (u8)cmd;
245 offset += nrchars; 245 offset += nrchars;
246 i++; 246 i++;
247 } 247 }
248 248
249 /* Each instruction is 16bit long. Check that length is even */ 249 /* Each instruction is 16bit long. Check that length is even */
250 if (i % 2) 250 if (i % 2)
251 goto err; 251 goto err;
252 252
253 program_size = i; 253 program_size = i;
254 for (i = 0; i < program_size; i++) 254 for (i = 0; i < program_size; i++)
255 lp55xx_write(chip, addr[idx] + i, pattern[i]); 255 lp55xx_write(chip, addr[idx] + i, pattern[i]);
256 256
257 return 0; 257 return 0;
258 258
259 err: 259 err:
260 dev_err(&chip->cl->dev, "wrong pattern format\n"); 260 dev_err(&chip->cl->dev, "wrong pattern format\n");
261 return -EINVAL; 261 return -EINVAL;
262 } 262 }
263 263
264 static void lp5521_firmware_loaded(struct lp55xx_chip *chip) 264 static void lp5521_firmware_loaded(struct lp55xx_chip *chip)
265 { 265 {
266 const struct firmware *fw = chip->fw; 266 const struct firmware *fw = chip->fw;
267 267
268 if (fw->size > LP5521_PROGRAM_LENGTH) { 268 if (fw->size > LP5521_PROGRAM_LENGTH) {
269 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 269 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
270 fw->size); 270 fw->size);
271 return; 271 return;
272 } 272 }
273 273
274 /* 274 /*
275 * Program momery sequence 275 * Program momery sequence
276 * 1) set engine mode to "LOAD" 276 * 1) set engine mode to "LOAD"
277 * 2) write firmware data into program memory 277 * 2) write firmware data into program memory
278 */ 278 */
279 279
280 lp5521_load_engine(chip); 280 lp5521_load_engine(chip);
281 lp5521_update_program_memory(chip, fw->data, fw->size); 281 lp5521_update_program_memory(chip, fw->data, fw->size);
282 } 282 }
283 283
284 static int lp5521_post_init_device(struct lp55xx_chip *chip) 284 static int lp5521_post_init_device(struct lp55xx_chip *chip)
285 { 285 {
286 int ret; 286 int ret;
287 u8 val; 287 u8 val;
288 288
289 /* 289 /*
290 * Make sure that the chip is reset by reading back the r channel 290 * Make sure that the chip is reset by reading back the r channel
291 * current reg. This is dummy read is required on some platforms - 291 * current reg. This is dummy read is required on some platforms -
292 * otherwise further access to the R G B channels in the 292 * otherwise further access to the R G B channels in the
293 * LP5521_REG_ENABLE register will not have any effect - strange! 293 * LP5521_REG_ENABLE register will not have any effect - strange!
294 */ 294 */
295 ret = lp55xx_read(chip, LP5521_REG_R_CURRENT, &val); 295 ret = lp55xx_read(chip, LP5521_REG_R_CURRENT, &val);
296 if (ret) { 296 if (ret) {
297 dev_err(&chip->cl->dev, "error in resetting chip\n"); 297 dev_err(&chip->cl->dev, "error in resetting chip\n");
298 return ret; 298 return ret;
299 } 299 }
300 if (val != LP5521_REG_R_CURR_DEFAULT) { 300 if (val != LP5521_REG_R_CURR_DEFAULT) {
301 dev_err(&chip->cl->dev, 301 dev_err(&chip->cl->dev,
302 "unexpected data in register (expected 0x%x got 0x%x)\n", 302 "unexpected data in register (expected 0x%x got 0x%x)\n",
303 LP5521_REG_R_CURR_DEFAULT, val); 303 LP5521_REG_R_CURR_DEFAULT, val);
304 ret = -EINVAL; 304 ret = -EINVAL;
305 return ret; 305 return ret;
306 } 306 }
307 usleep_range(10000, 20000); 307 usleep_range(10000, 20000);
308 308
309 /* Set all PWMs to direct control mode */ 309 /* Set all PWMs to direct control mode */
310 ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT); 310 ret = lp55xx_write(chip, LP5521_REG_OP_MODE, LP5521_CMD_DIRECT);
311 311
312 /* Update configuration for the clock setting */ 312 /* Update configuration for the clock setting */
313 val = LP5521_DEFAULT_CFG; 313 val = LP5521_DEFAULT_CFG;
314 if (!lp55xx_is_extclk_used(chip)) 314 if (!lp55xx_is_extclk_used(chip))
315 val |= LP5521_CLK_INT; 315 val |= LP5521_CLK_INT;
316 316
317 ret = lp55xx_write(chip, LP5521_REG_CONFIG, val); 317 ret = lp55xx_write(chip, LP5521_REG_CONFIG, val);
318 if (ret) 318 if (ret)
319 return ret; 319 return ret;
320 320
321 /* Initialize all channels PWM to zero -> leds off */ 321 /* Initialize all channels PWM to zero -> leds off */
322 lp55xx_write(chip, LP5521_REG_R_PWM, 0); 322 lp55xx_write(chip, LP5521_REG_R_PWM, 0);
323 lp55xx_write(chip, LP5521_REG_G_PWM, 0); 323 lp55xx_write(chip, LP5521_REG_G_PWM, 0);
324 lp55xx_write(chip, LP5521_REG_B_PWM, 0); 324 lp55xx_write(chip, LP5521_REG_B_PWM, 0);
325 325
326 /* Set engines are set to run state when OP_MODE enables engines */ 326 /* Set engines are set to run state when OP_MODE enables engines */
327 ret = lp55xx_write(chip, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM); 327 ret = lp55xx_write(chip, LP5521_REG_ENABLE, LP5521_ENABLE_RUN_PROGRAM);
328 if (ret) 328 if (ret)
329 return ret; 329 return ret;
330 330
331 lp5521_wait_enable_done(); 331 lp5521_wait_enable_done();
332 332
333 return 0; 333 return 0;
334 } 334 }
335 335
336 static int lp5521_run_selftest(struct lp55xx_chip *chip, char *buf) 336 static int lp5521_run_selftest(struct lp55xx_chip *chip, char *buf)
337 { 337 {
338 struct lp55xx_platform_data *pdata = chip->pdata; 338 struct lp55xx_platform_data *pdata = chip->pdata;
339 int ret; 339 int ret;
340 u8 status; 340 u8 status;
341 341
342 ret = lp55xx_read(chip, LP5521_REG_STATUS, &status); 342 ret = lp55xx_read(chip, LP5521_REG_STATUS, &status);
343 if (ret < 0) 343 if (ret < 0)
344 return ret; 344 return ret;
345 345
346 if (pdata->clock_mode != LP55XX_CLOCK_EXT) 346 if (pdata->clock_mode != LP55XX_CLOCK_EXT)
347 return 0; 347 return 0;
348 348
349 /* Check that ext clock is really in use if requested */ 349 /* Check that ext clock is really in use if requested */
350 if ((status & LP5521_EXT_CLK_USED) == 0) 350 if ((status & LP5521_EXT_CLK_USED) == 0)
351 return -EIO; 351 return -EIO;
352 352
353 return 0; 353 return 0;
354 } 354 }
355 355
356 static void lp5521_led_brightness_work(struct work_struct *work) 356 static void lp5521_led_brightness_work(struct work_struct *work)
357 { 357 {
358 struct lp55xx_led *led = container_of(work, struct lp55xx_led, 358 struct lp55xx_led *led = container_of(work, struct lp55xx_led,
359 brightness_work); 359 brightness_work);
360 struct lp55xx_chip *chip = led->chip; 360 struct lp55xx_chip *chip = led->chip;
361 361
362 mutex_lock(&chip->lock); 362 mutex_lock(&chip->lock);
363 lp55xx_write(chip, LP5521_REG_LED_PWM_BASE + led->chan_nr, 363 lp55xx_write(chip, LP5521_REG_LED_PWM_BASE + led->chan_nr,
364 led->brightness); 364 led->brightness);
365 mutex_unlock(&chip->lock); 365 mutex_unlock(&chip->lock);
366 } 366 }
367 367
368 static ssize_t lp5521_selftest(struct device *dev, 368 static ssize_t lp5521_selftest(struct device *dev,
369 struct device_attribute *attr, 369 struct device_attribute *attr,
370 char *buf) 370 char *buf)
371 { 371 {
372 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 372 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
373 struct lp55xx_chip *chip = led->chip; 373 struct lp55xx_chip *chip = led->chip;
374 int ret; 374 int ret;
375 375
376 mutex_lock(&chip->lock); 376 mutex_lock(&chip->lock);
377 ret = lp5521_run_selftest(chip, buf); 377 ret = lp5521_run_selftest(chip, buf);
378 mutex_unlock(&chip->lock); 378 mutex_unlock(&chip->lock);
379 379
380 return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK"); 380 return scnprintf(buf, PAGE_SIZE, "%s\n", ret ? "FAIL" : "OK");
381 } 381 }
382 382
383 /* device attributes */ 383 /* device attributes */
384 static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL); 384 static DEVICE_ATTR(selftest, S_IRUGO, lp5521_selftest, NULL);
385 385
386 static struct attribute *lp5521_attributes[] = { 386 static struct attribute *lp5521_attributes[] = {
387 &dev_attr_selftest.attr, 387 &dev_attr_selftest.attr,
388 NULL 388 NULL
389 }; 389 };
390 390
391 static const struct attribute_group lp5521_group = { 391 static const struct attribute_group lp5521_group = {
392 .attrs = lp5521_attributes, 392 .attrs = lp5521_attributes,
393 }; 393 };
394 394
395 /* Chip specific configurations */ 395 /* Chip specific configurations */
396 static struct lp55xx_device_config lp5521_cfg = { 396 static struct lp55xx_device_config lp5521_cfg = {
397 .reset = { 397 .reset = {
398 .addr = LP5521_REG_RESET, 398 .addr = LP5521_REG_RESET,
399 .val = LP5521_RESET, 399 .val = LP5521_RESET,
400 }, 400 },
401 .enable = { 401 .enable = {
402 .addr = LP5521_REG_ENABLE, 402 .addr = LP5521_REG_ENABLE,
403 .val = LP5521_ENABLE_DEFAULT, 403 .val = LP5521_ENABLE_DEFAULT,
404 }, 404 },
405 .max_channel = LP5521_MAX_LEDS, 405 .max_channel = LP5521_MAX_LEDS,
406 .post_init_device = lp5521_post_init_device, 406 .post_init_device = lp5521_post_init_device,
407 .brightness_work_fn = lp5521_led_brightness_work, 407 .brightness_work_fn = lp5521_led_brightness_work,
408 .set_led_current = lp5521_set_led_current, 408 .set_led_current = lp5521_set_led_current,
409 .firmware_cb = lp5521_firmware_loaded, 409 .firmware_cb = lp5521_firmware_loaded,
410 .run_engine = lp5521_run_engine, 410 .run_engine = lp5521_run_engine,
411 .dev_attr_group = &lp5521_group, 411 .dev_attr_group = &lp5521_group,
412 }; 412 };
413 413
414 static int lp5521_probe(struct i2c_client *client, 414 static int lp5521_probe(struct i2c_client *client,
415 const struct i2c_device_id *id) 415 const struct i2c_device_id *id)
416 { 416 {
417 int ret; 417 int ret;
418 struct lp55xx_chip *chip; 418 struct lp55xx_chip *chip;
419 struct lp55xx_led *led; 419 struct lp55xx_led *led;
420 struct lp55xx_platform_data *pdata; 420 struct lp55xx_platform_data *pdata;
421 struct device_node *np = client->dev.of_node; 421 struct device_node *np = client->dev.of_node;
422 422
423 if (!client->dev.platform_data) { 423 if (!dev_get_platdata(&client->dev)) {
424 if (np) { 424 if (np) {
425 ret = lp55xx_of_populate_pdata(&client->dev, np); 425 ret = lp55xx_of_populate_pdata(&client->dev, np);
426 if (ret < 0) 426 if (ret < 0)
427 return ret; 427 return ret;
428 } else { 428 } else {
429 dev_err(&client->dev, "no platform data\n"); 429 dev_err(&client->dev, "no platform data\n");
430 return -EINVAL; 430 return -EINVAL;
431 } 431 }
432 } 432 }
433 pdata = client->dev.platform_data; 433 pdata = dev_get_platdata(&client->dev);
434 434
435 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 435 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
436 if (!chip) 436 if (!chip)
437 return -ENOMEM; 437 return -ENOMEM;
438 438
439 led = devm_kzalloc(&client->dev, 439 led = devm_kzalloc(&client->dev,
440 sizeof(*led) * pdata->num_channels, GFP_KERNEL); 440 sizeof(*led) * pdata->num_channels, GFP_KERNEL);
441 if (!led) 441 if (!led)
442 return -ENOMEM; 442 return -ENOMEM;
443 443
444 chip->cl = client; 444 chip->cl = client;
445 chip->pdata = pdata; 445 chip->pdata = pdata;
446 chip->cfg = &lp5521_cfg; 446 chip->cfg = &lp5521_cfg;
447 447
448 mutex_init(&chip->lock); 448 mutex_init(&chip->lock);
449 449
450 i2c_set_clientdata(client, led); 450 i2c_set_clientdata(client, led);
451 451
452 ret = lp55xx_init_device(chip); 452 ret = lp55xx_init_device(chip);
453 if (ret) 453 if (ret)
454 goto err_init; 454 goto err_init;
455 455
456 dev_info(&client->dev, "%s programmable led chip found\n", id->name); 456 dev_info(&client->dev, "%s programmable led chip found\n", id->name);
457 457
458 ret = lp55xx_register_leds(led, chip); 458 ret = lp55xx_register_leds(led, chip);
459 if (ret) 459 if (ret)
460 goto err_register_leds; 460 goto err_register_leds;
461 461
462 ret = lp55xx_register_sysfs(chip); 462 ret = lp55xx_register_sysfs(chip);
463 if (ret) { 463 if (ret) {
464 dev_err(&client->dev, "registering sysfs failed\n"); 464 dev_err(&client->dev, "registering sysfs failed\n");
465 goto err_register_sysfs; 465 goto err_register_sysfs;
466 } 466 }
467 467
468 return 0; 468 return 0;
469 469
470 err_register_sysfs: 470 err_register_sysfs:
471 lp55xx_unregister_leds(led, chip); 471 lp55xx_unregister_leds(led, chip);
472 err_register_leds: 472 err_register_leds:
473 lp55xx_deinit_device(chip); 473 lp55xx_deinit_device(chip);
474 err_init: 474 err_init:
475 return ret; 475 return ret;
476 } 476 }
477 477
478 static int lp5521_remove(struct i2c_client *client) 478 static int lp5521_remove(struct i2c_client *client)
479 { 479 {
480 struct lp55xx_led *led = i2c_get_clientdata(client); 480 struct lp55xx_led *led = i2c_get_clientdata(client);
481 struct lp55xx_chip *chip = led->chip; 481 struct lp55xx_chip *chip = led->chip;
482 482
483 lp5521_stop_engine(chip); 483 lp5521_stop_engine(chip);
484 lp55xx_unregister_sysfs(chip); 484 lp55xx_unregister_sysfs(chip);
485 lp55xx_unregister_leds(led, chip); 485 lp55xx_unregister_leds(led, chip);
486 lp55xx_deinit_device(chip); 486 lp55xx_deinit_device(chip);
487 487
488 return 0; 488 return 0;
489 } 489 }
490 490
491 static const struct i2c_device_id lp5521_id[] = { 491 static const struct i2c_device_id lp5521_id[] = {
492 { "lp5521", 0 }, /* Three channel chip */ 492 { "lp5521", 0 }, /* Three channel chip */
493 { } 493 { }
494 }; 494 };
495 MODULE_DEVICE_TABLE(i2c, lp5521_id); 495 MODULE_DEVICE_TABLE(i2c, lp5521_id);
496 496
497 #ifdef CONFIG_OF 497 #ifdef CONFIG_OF
498 static const struct of_device_id of_lp5521_leds_match[] = { 498 static const struct of_device_id of_lp5521_leds_match[] = {
499 { .compatible = "national,lp5521", }, 499 { .compatible = "national,lp5521", },
500 {}, 500 {},
501 }; 501 };
502 502
503 MODULE_DEVICE_TABLE(of, of_lp5521_leds_match); 503 MODULE_DEVICE_TABLE(of, of_lp5521_leds_match);
504 #endif 504 #endif
505 static struct i2c_driver lp5521_driver = { 505 static struct i2c_driver lp5521_driver = {
506 .driver = { 506 .driver = {
507 .name = "lp5521", 507 .name = "lp5521",
508 .of_match_table = of_match_ptr(of_lp5521_leds_match), 508 .of_match_table = of_match_ptr(of_lp5521_leds_match),
509 }, 509 },
510 .probe = lp5521_probe, 510 .probe = lp5521_probe,
511 .remove = lp5521_remove, 511 .remove = lp5521_remove,
512 .id_table = lp5521_id, 512 .id_table = lp5521_id,
513 }; 513 };
514 514
515 module_i2c_driver(lp5521_driver); 515 module_i2c_driver(lp5521_driver);
516 516
517 MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo"); 517 MODULE_AUTHOR("Mathias Nyman, Yuri Zaporozhets, Samu Onkalo");
518 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 518 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
519 MODULE_DESCRIPTION("LP5521 LED engine"); 519 MODULE_DESCRIPTION("LP5521 LED engine");
520 MODULE_LICENSE("GPL v2"); 520 MODULE_LICENSE("GPL v2");
521 521
drivers/leds/leds-lp5523.c
1 /* 1 /*
2 * lp5523.c - LP5523 LED Driver 2 * lp5523.c - LP5523 LED Driver
3 * 3 *
4 * Copyright (C) 2010 Nokia Corporation 4 * Copyright (C) 2010 Nokia Corporation
5 * Copyright (C) 2012 Texas Instruments 5 * Copyright (C) 2012 Texas Instruments
6 * 6 *
7 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com> 7 * Contact: Samu Onkalo <samu.p.onkalo@nokia.com>
8 * Milo(Woogyom) Kim <milo.kim@ti.com> 8 * Milo(Woogyom) Kim <milo.kim@ti.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or 10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License 11 * modify it under the terms of the GNU General Public License
12 * version 2 as published by the Free Software Foundation. 12 * version 2 as published by the Free Software Foundation.
13 * 13 *
14 * This program is distributed in the hope that it will be useful, but 14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details. 17 * General Public License for more details.
18 * 18 *
19 * You should have received a copy of the GNU General Public License 19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software 20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
22 * 02110-1301 USA 22 * 02110-1301 USA
23 */ 23 */
24 24
25 #include <linux/delay.h> 25 #include <linux/delay.h>
26 #include <linux/firmware.h> 26 #include <linux/firmware.h>
27 #include <linux/i2c.h> 27 #include <linux/i2c.h>
28 #include <linux/init.h> 28 #include <linux/init.h>
29 #include <linux/leds.h> 29 #include <linux/leds.h>
30 #include <linux/module.h> 30 #include <linux/module.h>
31 #include <linux/mutex.h> 31 #include <linux/mutex.h>
32 #include <linux/platform_data/leds-lp55xx.h> 32 #include <linux/platform_data/leds-lp55xx.h>
33 #include <linux/slab.h> 33 #include <linux/slab.h>
34 34
35 #include "leds-lp55xx-common.h" 35 #include "leds-lp55xx-common.h"
36 36
37 #define LP5523_PROGRAM_LENGTH 32 37 #define LP5523_PROGRAM_LENGTH 32
38 #define LP5523_MAX_LEDS 9 38 #define LP5523_MAX_LEDS 9
39 39
40 /* Registers */ 40 /* Registers */
41 #define LP5523_REG_ENABLE 0x00 41 #define LP5523_REG_ENABLE 0x00
42 #define LP5523_REG_OP_MODE 0x01 42 #define LP5523_REG_OP_MODE 0x01
43 #define LP5523_REG_ENABLE_LEDS_MSB 0x04 43 #define LP5523_REG_ENABLE_LEDS_MSB 0x04
44 #define LP5523_REG_ENABLE_LEDS_LSB 0x05 44 #define LP5523_REG_ENABLE_LEDS_LSB 0x05
45 #define LP5523_REG_LED_PWM_BASE 0x16 45 #define LP5523_REG_LED_PWM_BASE 0x16
46 #define LP5523_REG_LED_CURRENT_BASE 0x26 46 #define LP5523_REG_LED_CURRENT_BASE 0x26
47 #define LP5523_REG_CONFIG 0x36 47 #define LP5523_REG_CONFIG 0x36
48 #define LP5523_REG_STATUS 0x3A 48 #define LP5523_REG_STATUS 0x3A
49 #define LP5523_REG_RESET 0x3D 49 #define LP5523_REG_RESET 0x3D
50 #define LP5523_REG_LED_TEST_CTRL 0x41 50 #define LP5523_REG_LED_TEST_CTRL 0x41
51 #define LP5523_REG_LED_TEST_ADC 0x42 51 #define LP5523_REG_LED_TEST_ADC 0x42
52 #define LP5523_REG_PROG_PAGE_SEL 0x4F 52 #define LP5523_REG_PROG_PAGE_SEL 0x4F
53 #define LP5523_REG_PROG_MEM 0x50 53 #define LP5523_REG_PROG_MEM 0x50
54 54
55 /* Bit description in registers */ 55 /* Bit description in registers */
56 #define LP5523_ENABLE 0x40 56 #define LP5523_ENABLE 0x40
57 #define LP5523_AUTO_INC 0x40 57 #define LP5523_AUTO_INC 0x40
58 #define LP5523_PWR_SAVE 0x20 58 #define LP5523_PWR_SAVE 0x20
59 #define LP5523_PWM_PWR_SAVE 0x04 59 #define LP5523_PWM_PWR_SAVE 0x04
60 #define LP5523_CP_AUTO 0x18 60 #define LP5523_CP_AUTO 0x18
61 #define LP5523_AUTO_CLK 0x02 61 #define LP5523_AUTO_CLK 0x02
62 62
63 #define LP5523_EN_LEDTEST 0x80 63 #define LP5523_EN_LEDTEST 0x80
64 #define LP5523_LEDTEST_DONE 0x80 64 #define LP5523_LEDTEST_DONE 0x80
65 #define LP5523_RESET 0xFF 65 #define LP5523_RESET 0xFF
66 #define LP5523_ADC_SHORTCIRC_LIM 80 66 #define LP5523_ADC_SHORTCIRC_LIM 80
67 #define LP5523_EXT_CLK_USED 0x08 67 #define LP5523_EXT_CLK_USED 0x08
68 68
69 /* Memory Page Selection */ 69 /* Memory Page Selection */
70 #define LP5523_PAGE_ENG1 0 70 #define LP5523_PAGE_ENG1 0
71 #define LP5523_PAGE_ENG2 1 71 #define LP5523_PAGE_ENG2 1
72 #define LP5523_PAGE_ENG3 2 72 #define LP5523_PAGE_ENG3 2
73 73
74 /* Program Memory Operations */ 74 /* Program Memory Operations */
75 #define LP5523_MODE_ENG1_M 0x30 /* Operation Mode Register */ 75 #define LP5523_MODE_ENG1_M 0x30 /* Operation Mode Register */
76 #define LP5523_MODE_ENG2_M 0x0C 76 #define LP5523_MODE_ENG2_M 0x0C
77 #define LP5523_MODE_ENG3_M 0x03 77 #define LP5523_MODE_ENG3_M 0x03
78 #define LP5523_LOAD_ENG1 0x10 78 #define LP5523_LOAD_ENG1 0x10
79 #define LP5523_LOAD_ENG2 0x04 79 #define LP5523_LOAD_ENG2 0x04
80 #define LP5523_LOAD_ENG3 0x01 80 #define LP5523_LOAD_ENG3 0x01
81 81
82 #define LP5523_ENG1_IS_LOADING(mode) \ 82 #define LP5523_ENG1_IS_LOADING(mode) \
83 ((mode & LP5523_MODE_ENG1_M) == LP5523_LOAD_ENG1) 83 ((mode & LP5523_MODE_ENG1_M) == LP5523_LOAD_ENG1)
84 #define LP5523_ENG2_IS_LOADING(mode) \ 84 #define LP5523_ENG2_IS_LOADING(mode) \
85 ((mode & LP5523_MODE_ENG2_M) == LP5523_LOAD_ENG2) 85 ((mode & LP5523_MODE_ENG2_M) == LP5523_LOAD_ENG2)
86 #define LP5523_ENG3_IS_LOADING(mode) \ 86 #define LP5523_ENG3_IS_LOADING(mode) \
87 ((mode & LP5523_MODE_ENG3_M) == LP5523_LOAD_ENG3) 87 ((mode & LP5523_MODE_ENG3_M) == LP5523_LOAD_ENG3)
88 88
89 #define LP5523_EXEC_ENG1_M 0x30 /* Enable Register */ 89 #define LP5523_EXEC_ENG1_M 0x30 /* Enable Register */
90 #define LP5523_EXEC_ENG2_M 0x0C 90 #define LP5523_EXEC_ENG2_M 0x0C
91 #define LP5523_EXEC_ENG3_M 0x03 91 #define LP5523_EXEC_ENG3_M 0x03
92 #define LP5523_EXEC_M 0x3F 92 #define LP5523_EXEC_M 0x3F
93 #define LP5523_RUN_ENG1 0x20 93 #define LP5523_RUN_ENG1 0x20
94 #define LP5523_RUN_ENG2 0x08 94 #define LP5523_RUN_ENG2 0x08
95 #define LP5523_RUN_ENG3 0x02 95 #define LP5523_RUN_ENG3 0x02
96 96
97 enum lp5523_chip_id { 97 enum lp5523_chip_id {
98 LP5523, 98 LP5523,
99 LP55231, 99 LP55231,
100 }; 100 };
101 101
102 static inline void lp5523_wait_opmode_done(void) 102 static inline void lp5523_wait_opmode_done(void)
103 { 103 {
104 usleep_range(1000, 2000); 104 usleep_range(1000, 2000);
105 } 105 }
106 106
107 static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current) 107 static void lp5523_set_led_current(struct lp55xx_led *led, u8 led_current)
108 { 108 {
109 led->led_current = led_current; 109 led->led_current = led_current;
110 lp55xx_write(led->chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr, 110 lp55xx_write(led->chip, LP5523_REG_LED_CURRENT_BASE + led->chan_nr,
111 led_current); 111 led_current);
112 } 112 }
113 113
114 static int lp5523_post_init_device(struct lp55xx_chip *chip) 114 static int lp5523_post_init_device(struct lp55xx_chip *chip)
115 { 115 {
116 int ret; 116 int ret;
117 117
118 ret = lp55xx_write(chip, LP5523_REG_ENABLE, LP5523_ENABLE); 118 ret = lp55xx_write(chip, LP5523_REG_ENABLE, LP5523_ENABLE);
119 if (ret) 119 if (ret)
120 return ret; 120 return ret;
121 121
122 /* Chip startup time is 500 us, 1 - 2 ms gives some margin */ 122 /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
123 usleep_range(1000, 2000); 123 usleep_range(1000, 2000);
124 124
125 ret = lp55xx_write(chip, LP5523_REG_CONFIG, 125 ret = lp55xx_write(chip, LP5523_REG_CONFIG,
126 LP5523_AUTO_INC | LP5523_PWR_SAVE | 126 LP5523_AUTO_INC | LP5523_PWR_SAVE |
127 LP5523_CP_AUTO | LP5523_AUTO_CLK | 127 LP5523_CP_AUTO | LP5523_AUTO_CLK |
128 LP5523_PWM_PWR_SAVE); 128 LP5523_PWM_PWR_SAVE);
129 if (ret) 129 if (ret)
130 return ret; 130 return ret;
131 131
132 /* turn on all leds */ 132 /* turn on all leds */
133 ret = lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_MSB, 0x01); 133 ret = lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_MSB, 0x01);
134 if (ret) 134 if (ret)
135 return ret; 135 return ret;
136 136
137 return lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_LSB, 0xff); 137 return lp55xx_write(chip, LP5523_REG_ENABLE_LEDS_LSB, 0xff);
138 } 138 }
139 139
140 static void lp5523_load_engine(struct lp55xx_chip *chip) 140 static void lp5523_load_engine(struct lp55xx_chip *chip)
141 { 141 {
142 enum lp55xx_engine_index idx = chip->engine_idx; 142 enum lp55xx_engine_index idx = chip->engine_idx;
143 u8 mask[] = { 143 u8 mask[] = {
144 [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M, 144 [LP55XX_ENGINE_1] = LP5523_MODE_ENG1_M,
145 [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M, 145 [LP55XX_ENGINE_2] = LP5523_MODE_ENG2_M,
146 [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M, 146 [LP55XX_ENGINE_3] = LP5523_MODE_ENG3_M,
147 }; 147 };
148 148
149 u8 val[] = { 149 u8 val[] = {
150 [LP55XX_ENGINE_1] = LP5523_LOAD_ENG1, 150 [LP55XX_ENGINE_1] = LP5523_LOAD_ENG1,
151 [LP55XX_ENGINE_2] = LP5523_LOAD_ENG2, 151 [LP55XX_ENGINE_2] = LP5523_LOAD_ENG2,
152 [LP55XX_ENGINE_3] = LP5523_LOAD_ENG3, 152 [LP55XX_ENGINE_3] = LP5523_LOAD_ENG3,
153 }; 153 };
154 154
155 u8 page_sel[] = { 155 u8 page_sel[] = {
156 [LP55XX_ENGINE_1] = LP5523_PAGE_ENG1, 156 [LP55XX_ENGINE_1] = LP5523_PAGE_ENG1,
157 [LP55XX_ENGINE_2] = LP5523_PAGE_ENG2, 157 [LP55XX_ENGINE_2] = LP5523_PAGE_ENG2,
158 [LP55XX_ENGINE_3] = LP5523_PAGE_ENG3, 158 [LP55XX_ENGINE_3] = LP5523_PAGE_ENG3,
159 }; 159 };
160 160
161 lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], val[idx]); 161 lp55xx_update_bits(chip, LP5523_REG_OP_MODE, mask[idx], val[idx]);
162 162
163 lp5523_wait_opmode_done(); 163 lp5523_wait_opmode_done();
164 164
165 lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]); 165 lp55xx_write(chip, LP5523_REG_PROG_PAGE_SEL, page_sel[idx]);
166 } 166 }
167 167
168 static void lp5523_stop_engine(struct lp55xx_chip *chip) 168 static void lp5523_stop_engine(struct lp55xx_chip *chip)
169 { 169 {
170 lp55xx_write(chip, LP5523_REG_OP_MODE, 0); 170 lp55xx_write(chip, LP5523_REG_OP_MODE, 0);
171 lp5523_wait_opmode_done(); 171 lp5523_wait_opmode_done();
172 } 172 }
173 173
174 static void lp5523_turn_off_channels(struct lp55xx_chip *chip) 174 static void lp5523_turn_off_channels(struct lp55xx_chip *chip)
175 { 175 {
176 int i; 176 int i;
177 177
178 for (i = 0; i < LP5523_MAX_LEDS; i++) 178 for (i = 0; i < LP5523_MAX_LEDS; i++)
179 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0); 179 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0);
180 } 180 }
181 181
182 static void lp5523_run_engine(struct lp55xx_chip *chip, bool start) 182 static void lp5523_run_engine(struct lp55xx_chip *chip, bool start)
183 { 183 {
184 int ret; 184 int ret;
185 u8 mode; 185 u8 mode;
186 u8 exec; 186 u8 exec;
187 187
188 /* stop engine */ 188 /* stop engine */
189 if (!start) { 189 if (!start) {
190 lp5523_stop_engine(chip); 190 lp5523_stop_engine(chip);
191 lp5523_turn_off_channels(chip); 191 lp5523_turn_off_channels(chip);
192 return; 192 return;
193 } 193 }
194 194
195 /* 195 /*
196 * To run the engine, 196 * To run the engine,
197 * operation mode and enable register should updated at the same time 197 * operation mode and enable register should updated at the same time
198 */ 198 */
199 199
200 ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode); 200 ret = lp55xx_read(chip, LP5523_REG_OP_MODE, &mode);
201 if (ret) 201 if (ret)
202 return; 202 return;
203 203
204 ret = lp55xx_read(chip, LP5523_REG_ENABLE, &exec); 204 ret = lp55xx_read(chip, LP5523_REG_ENABLE, &exec);
205 if (ret) 205 if (ret)
206 return; 206 return;
207 207
208 /* change operation mode to RUN only when each engine is loading */ 208 /* change operation mode to RUN only when each engine is loading */
209 if (LP5523_ENG1_IS_LOADING(mode)) { 209 if (LP5523_ENG1_IS_LOADING(mode)) {
210 mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1; 210 mode = (mode & ~LP5523_MODE_ENG1_M) | LP5523_RUN_ENG1;
211 exec = (exec & ~LP5523_EXEC_ENG1_M) | LP5523_RUN_ENG1; 211 exec = (exec & ~LP5523_EXEC_ENG1_M) | LP5523_RUN_ENG1;
212 } 212 }
213 213
214 if (LP5523_ENG2_IS_LOADING(mode)) { 214 if (LP5523_ENG2_IS_LOADING(mode)) {
215 mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2; 215 mode = (mode & ~LP5523_MODE_ENG2_M) | LP5523_RUN_ENG2;
216 exec = (exec & ~LP5523_EXEC_ENG2_M) | LP5523_RUN_ENG2; 216 exec = (exec & ~LP5523_EXEC_ENG2_M) | LP5523_RUN_ENG2;
217 } 217 }
218 218
219 if (LP5523_ENG3_IS_LOADING(mode)) { 219 if (LP5523_ENG3_IS_LOADING(mode)) {
220 mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3; 220 mode = (mode & ~LP5523_MODE_ENG3_M) | LP5523_RUN_ENG3;
221 exec = (exec & ~LP5523_EXEC_ENG3_M) | LP5523_RUN_ENG3; 221 exec = (exec & ~LP5523_EXEC_ENG3_M) | LP5523_RUN_ENG3;
222 } 222 }
223 223
224 lp55xx_write(chip, LP5523_REG_OP_MODE, mode); 224 lp55xx_write(chip, LP5523_REG_OP_MODE, mode);
225 lp5523_wait_opmode_done(); 225 lp5523_wait_opmode_done();
226 226
227 lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec); 227 lp55xx_update_bits(chip, LP5523_REG_ENABLE, LP5523_EXEC_M, exec);
228 } 228 }
229 229
230 static int lp5523_update_program_memory(struct lp55xx_chip *chip, 230 static int lp5523_update_program_memory(struct lp55xx_chip *chip,
231 const u8 *data, size_t size) 231 const u8 *data, size_t size)
232 { 232 {
233 u8 pattern[LP5523_PROGRAM_LENGTH] = {0}; 233 u8 pattern[LP5523_PROGRAM_LENGTH] = {0};
234 unsigned cmd; 234 unsigned cmd;
235 char c[3]; 235 char c[3];
236 int update_size; 236 int update_size;
237 int nrchars; 237 int nrchars;
238 int offset = 0; 238 int offset = 0;
239 int ret; 239 int ret;
240 int i; 240 int i;
241 241
242 /* clear program memory before updating */ 242 /* clear program memory before updating */
243 for (i = 0; i < LP5523_PROGRAM_LENGTH; i++) 243 for (i = 0; i < LP5523_PROGRAM_LENGTH; i++)
244 lp55xx_write(chip, LP5523_REG_PROG_MEM + i, 0); 244 lp55xx_write(chip, LP5523_REG_PROG_MEM + i, 0);
245 245
246 i = 0; 246 i = 0;
247 while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) { 247 while ((offset < size - 1) && (i < LP5523_PROGRAM_LENGTH)) {
248 /* separate sscanfs because length is working only for %s */ 248 /* separate sscanfs because length is working only for %s */
249 ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 249 ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
250 if (ret != 1) 250 if (ret != 1)
251 goto err; 251 goto err;
252 252
253 ret = sscanf(c, "%2x", &cmd); 253 ret = sscanf(c, "%2x", &cmd);
254 if (ret != 1) 254 if (ret != 1)
255 goto err; 255 goto err;
256 256
257 pattern[i] = (u8)cmd; 257 pattern[i] = (u8)cmd;
258 offset += nrchars; 258 offset += nrchars;
259 i++; 259 i++;
260 } 260 }
261 261
262 /* Each instruction is 16bit long. Check that length is even */ 262 /* Each instruction is 16bit long. Check that length is even */
263 if (i % 2) 263 if (i % 2)
264 goto err; 264 goto err;
265 265
266 update_size = i; 266 update_size = i;
267 for (i = 0; i < update_size; i++) 267 for (i = 0; i < update_size; i++)
268 lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]); 268 lp55xx_write(chip, LP5523_REG_PROG_MEM + i, pattern[i]);
269 269
270 return 0; 270 return 0;
271 271
272 err: 272 err:
273 dev_err(&chip->cl->dev, "wrong pattern format\n"); 273 dev_err(&chip->cl->dev, "wrong pattern format\n");
274 return -EINVAL; 274 return -EINVAL;
275 } 275 }
276 276
277 static void lp5523_firmware_loaded(struct lp55xx_chip *chip) 277 static void lp5523_firmware_loaded(struct lp55xx_chip *chip)
278 { 278 {
279 const struct firmware *fw = chip->fw; 279 const struct firmware *fw = chip->fw;
280 280
281 if (fw->size > LP5523_PROGRAM_LENGTH) { 281 if (fw->size > LP5523_PROGRAM_LENGTH) {
282 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 282 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
283 fw->size); 283 fw->size);
284 return; 284 return;
285 } 285 }
286 286
287 /* 287 /*
288 * Program momery sequence 288 * Program momery sequence
289 * 1) set engine mode to "LOAD" 289 * 1) set engine mode to "LOAD"
290 * 2) write firmware data into program memory 290 * 2) write firmware data into program memory
291 */ 291 */
292 292
293 lp5523_load_engine(chip); 293 lp5523_load_engine(chip);
294 lp5523_update_program_memory(chip, fw->data, fw->size); 294 lp5523_update_program_memory(chip, fw->data, fw->size);
295 } 295 }
296 296
297 static ssize_t lp5523_selftest(struct device *dev, 297 static ssize_t lp5523_selftest(struct device *dev,
298 struct device_attribute *attr, 298 struct device_attribute *attr,
299 char *buf) 299 char *buf)
300 { 300 {
301 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 301 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
302 struct lp55xx_chip *chip = led->chip; 302 struct lp55xx_chip *chip = led->chip;
303 struct lp55xx_platform_data *pdata = chip->pdata; 303 struct lp55xx_platform_data *pdata = chip->pdata;
304 int i, ret, pos = 0; 304 int i, ret, pos = 0;
305 u8 status, adc, vdd; 305 u8 status, adc, vdd;
306 306
307 mutex_lock(&chip->lock); 307 mutex_lock(&chip->lock);
308 308
309 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); 309 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
310 if (ret < 0) 310 if (ret < 0)
311 goto fail; 311 goto fail;
312 312
313 /* Check that ext clock is really in use if requested */ 313 /* Check that ext clock is really in use if requested */
314 if (pdata->clock_mode == LP55XX_CLOCK_EXT) { 314 if (pdata->clock_mode == LP55XX_CLOCK_EXT) {
315 if ((status & LP5523_EXT_CLK_USED) == 0) 315 if ((status & LP5523_EXT_CLK_USED) == 0)
316 goto fail; 316 goto fail;
317 } 317 }
318 318
319 /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */ 319 /* Measure VDD (i.e. VBAT) first (channel 16 corresponds to VDD) */
320 lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL, LP5523_EN_LEDTEST | 16); 320 lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL, LP5523_EN_LEDTEST | 16);
321 usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */ 321 usleep_range(3000, 6000); /* ADC conversion time is typically 2.7 ms */
322 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); 322 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
323 if (ret < 0) 323 if (ret < 0)
324 goto fail; 324 goto fail;
325 325
326 if (!(status & LP5523_LEDTEST_DONE)) 326 if (!(status & LP5523_LEDTEST_DONE))
327 usleep_range(3000, 6000); /* Was not ready. Wait little bit */ 327 usleep_range(3000, 6000); /* Was not ready. Wait little bit */
328 328
329 ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &vdd); 329 ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &vdd);
330 if (ret < 0) 330 if (ret < 0)
331 goto fail; 331 goto fail;
332 332
333 vdd--; /* There may be some fluctuation in measurement */ 333 vdd--; /* There may be some fluctuation in measurement */
334 334
335 for (i = 0; i < LP5523_MAX_LEDS; i++) { 335 for (i = 0; i < LP5523_MAX_LEDS; i++) {
336 /* Skip non-existing channels */ 336 /* Skip non-existing channels */
337 if (pdata->led_config[i].led_current == 0) 337 if (pdata->led_config[i].led_current == 0)
338 continue; 338 continue;
339 339
340 /* Set default current */ 340 /* Set default current */
341 lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i, 341 lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
342 pdata->led_config[i].led_current); 342 pdata->led_config[i].led_current);
343 343
344 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0xff); 344 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0xff);
345 /* let current stabilize 2 - 4ms before measurements start */ 345 /* let current stabilize 2 - 4ms before measurements start */
346 usleep_range(2000, 4000); 346 usleep_range(2000, 4000);
347 lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL, 347 lp55xx_write(chip, LP5523_REG_LED_TEST_CTRL,
348 LP5523_EN_LEDTEST | i); 348 LP5523_EN_LEDTEST | i);
349 /* ADC conversion time is 2.7 ms typically */ 349 /* ADC conversion time is 2.7 ms typically */
350 usleep_range(3000, 6000); 350 usleep_range(3000, 6000);
351 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status); 351 ret = lp55xx_read(chip, LP5523_REG_STATUS, &status);
352 if (ret < 0) 352 if (ret < 0)
353 goto fail; 353 goto fail;
354 354
355 if (!(status & LP5523_LEDTEST_DONE)) 355 if (!(status & LP5523_LEDTEST_DONE))
356 usleep_range(3000, 6000);/* Was not ready. Wait. */ 356 usleep_range(3000, 6000);/* Was not ready. Wait. */
357 357
358 ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc); 358 ret = lp55xx_read(chip, LP5523_REG_LED_TEST_ADC, &adc);
359 if (ret < 0) 359 if (ret < 0)
360 goto fail; 360 goto fail;
361 361
362 if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM) 362 if (adc >= vdd || adc < LP5523_ADC_SHORTCIRC_LIM)
363 pos += sprintf(buf + pos, "LED %d FAIL\n", i); 363 pos += sprintf(buf + pos, "LED %d FAIL\n", i);
364 364
365 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0x00); 365 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + i, 0x00);
366 366
367 /* Restore current */ 367 /* Restore current */
368 lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i, 368 lp55xx_write(chip, LP5523_REG_LED_CURRENT_BASE + i,
369 led->led_current); 369 led->led_current);
370 led++; 370 led++;
371 } 371 }
372 if (pos == 0) 372 if (pos == 0)
373 pos = sprintf(buf, "OK\n"); 373 pos = sprintf(buf, "OK\n");
374 goto release_lock; 374 goto release_lock;
375 fail: 375 fail:
376 pos = sprintf(buf, "FAIL\n"); 376 pos = sprintf(buf, "FAIL\n");
377 377
378 release_lock: 378 release_lock:
379 mutex_unlock(&chip->lock); 379 mutex_unlock(&chip->lock);
380 380
381 return pos; 381 return pos;
382 } 382 }
383 383
384 static void lp5523_led_brightness_work(struct work_struct *work) 384 static void lp5523_led_brightness_work(struct work_struct *work)
385 { 385 {
386 struct lp55xx_led *led = container_of(work, struct lp55xx_led, 386 struct lp55xx_led *led = container_of(work, struct lp55xx_led,
387 brightness_work); 387 brightness_work);
388 struct lp55xx_chip *chip = led->chip; 388 struct lp55xx_chip *chip = led->chip;
389 389
390 mutex_lock(&chip->lock); 390 mutex_lock(&chip->lock);
391 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr, 391 lp55xx_write(chip, LP5523_REG_LED_PWM_BASE + led->chan_nr,
392 led->brightness); 392 led->brightness);
393 mutex_unlock(&chip->lock); 393 mutex_unlock(&chip->lock);
394 } 394 }
395 395
396 static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL); 396 static DEVICE_ATTR(selftest, S_IRUGO, lp5523_selftest, NULL);
397 397
398 static struct attribute *lp5523_attributes[] = { 398 static struct attribute *lp5523_attributes[] = {
399 &dev_attr_selftest.attr, 399 &dev_attr_selftest.attr,
400 NULL, 400 NULL,
401 }; 401 };
402 402
403 static const struct attribute_group lp5523_group = { 403 static const struct attribute_group lp5523_group = {
404 .attrs = lp5523_attributes, 404 .attrs = lp5523_attributes,
405 }; 405 };
406 406
407 /* Chip specific configurations */ 407 /* Chip specific configurations */
408 static struct lp55xx_device_config lp5523_cfg = { 408 static struct lp55xx_device_config lp5523_cfg = {
409 .reset = { 409 .reset = {
410 .addr = LP5523_REG_RESET, 410 .addr = LP5523_REG_RESET,
411 .val = LP5523_RESET, 411 .val = LP5523_RESET,
412 }, 412 },
413 .enable = { 413 .enable = {
414 .addr = LP5523_REG_ENABLE, 414 .addr = LP5523_REG_ENABLE,
415 .val = LP5523_ENABLE, 415 .val = LP5523_ENABLE,
416 }, 416 },
417 .max_channel = LP5523_MAX_LEDS, 417 .max_channel = LP5523_MAX_LEDS,
418 .post_init_device = lp5523_post_init_device, 418 .post_init_device = lp5523_post_init_device,
419 .brightness_work_fn = lp5523_led_brightness_work, 419 .brightness_work_fn = lp5523_led_brightness_work,
420 .set_led_current = lp5523_set_led_current, 420 .set_led_current = lp5523_set_led_current,
421 .firmware_cb = lp5523_firmware_loaded, 421 .firmware_cb = lp5523_firmware_loaded,
422 .run_engine = lp5523_run_engine, 422 .run_engine = lp5523_run_engine,
423 .dev_attr_group = &lp5523_group, 423 .dev_attr_group = &lp5523_group,
424 }; 424 };
425 425
426 static int lp5523_probe(struct i2c_client *client, 426 static int lp5523_probe(struct i2c_client *client,
427 const struct i2c_device_id *id) 427 const struct i2c_device_id *id)
428 { 428 {
429 int ret; 429 int ret;
430 struct lp55xx_chip *chip; 430 struct lp55xx_chip *chip;
431 struct lp55xx_led *led; 431 struct lp55xx_led *led;
432 struct lp55xx_platform_data *pdata; 432 struct lp55xx_platform_data *pdata;
433 struct device_node *np = client->dev.of_node; 433 struct device_node *np = client->dev.of_node;
434 434
435 if (!client->dev.platform_data) { 435 if (!dev_get_platdata(&client->dev)) {
436 if (np) { 436 if (np) {
437 ret = lp55xx_of_populate_pdata(&client->dev, np); 437 ret = lp55xx_of_populate_pdata(&client->dev, np);
438 if (ret < 0) 438 if (ret < 0)
439 return ret; 439 return ret;
440 } else { 440 } else {
441 dev_err(&client->dev, "no platform data\n"); 441 dev_err(&client->dev, "no platform data\n");
442 return -EINVAL; 442 return -EINVAL;
443 } 443 }
444 } 444 }
445 pdata = client->dev.platform_data; 445 pdata = dev_get_platdata(&client->dev);
446 446
447 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 447 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
448 if (!chip) 448 if (!chip)
449 return -ENOMEM; 449 return -ENOMEM;
450 450
451 led = devm_kzalloc(&client->dev, 451 led = devm_kzalloc(&client->dev,
452 sizeof(*led) * pdata->num_channels, GFP_KERNEL); 452 sizeof(*led) * pdata->num_channels, GFP_KERNEL);
453 if (!led) 453 if (!led)
454 return -ENOMEM; 454 return -ENOMEM;
455 455
456 chip->cl = client; 456 chip->cl = client;
457 chip->pdata = pdata; 457 chip->pdata = pdata;
458 chip->cfg = &lp5523_cfg; 458 chip->cfg = &lp5523_cfg;
459 459
460 mutex_init(&chip->lock); 460 mutex_init(&chip->lock);
461 461
462 i2c_set_clientdata(client, led); 462 i2c_set_clientdata(client, led);
463 463
464 ret = lp55xx_init_device(chip); 464 ret = lp55xx_init_device(chip);
465 if (ret) 465 if (ret)
466 goto err_init; 466 goto err_init;
467 467
468 dev_info(&client->dev, "%s Programmable led chip found\n", id->name); 468 dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
469 469
470 ret = lp55xx_register_leds(led, chip); 470 ret = lp55xx_register_leds(led, chip);
471 if (ret) 471 if (ret)
472 goto err_register_leds; 472 goto err_register_leds;
473 473
474 ret = lp55xx_register_sysfs(chip); 474 ret = lp55xx_register_sysfs(chip);
475 if (ret) { 475 if (ret) {
476 dev_err(&client->dev, "registering sysfs failed\n"); 476 dev_err(&client->dev, "registering sysfs failed\n");
477 goto err_register_sysfs; 477 goto err_register_sysfs;
478 } 478 }
479 479
480 return 0; 480 return 0;
481 481
482 err_register_sysfs: 482 err_register_sysfs:
483 lp55xx_unregister_leds(led, chip); 483 lp55xx_unregister_leds(led, chip);
484 err_register_leds: 484 err_register_leds:
485 lp55xx_deinit_device(chip); 485 lp55xx_deinit_device(chip);
486 err_init: 486 err_init:
487 return ret; 487 return ret;
488 } 488 }
489 489
490 static int lp5523_remove(struct i2c_client *client) 490 static int lp5523_remove(struct i2c_client *client)
491 { 491 {
492 struct lp55xx_led *led = i2c_get_clientdata(client); 492 struct lp55xx_led *led = i2c_get_clientdata(client);
493 struct lp55xx_chip *chip = led->chip; 493 struct lp55xx_chip *chip = led->chip;
494 494
495 lp5523_stop_engine(chip); 495 lp5523_stop_engine(chip);
496 lp55xx_unregister_sysfs(chip); 496 lp55xx_unregister_sysfs(chip);
497 lp55xx_unregister_leds(led, chip); 497 lp55xx_unregister_leds(led, chip);
498 lp55xx_deinit_device(chip); 498 lp55xx_deinit_device(chip);
499 499
500 return 0; 500 return 0;
501 } 501 }
502 502
503 static const struct i2c_device_id lp5523_id[] = { 503 static const struct i2c_device_id lp5523_id[] = {
504 { "lp5523", LP5523 }, 504 { "lp5523", LP5523 },
505 { "lp55231", LP55231 }, 505 { "lp55231", LP55231 },
506 { } 506 { }
507 }; 507 };
508 508
509 MODULE_DEVICE_TABLE(i2c, lp5523_id); 509 MODULE_DEVICE_TABLE(i2c, lp5523_id);
510 510
511 #ifdef CONFIG_OF 511 #ifdef CONFIG_OF
512 static const struct of_device_id of_lp5523_leds_match[] = { 512 static const struct of_device_id of_lp5523_leds_match[] = {
513 { .compatible = "national,lp5523", }, 513 { .compatible = "national,lp5523", },
514 {}, 514 {},
515 }; 515 };
516 516
517 MODULE_DEVICE_TABLE(of, of_lp5523_leds_match); 517 MODULE_DEVICE_TABLE(of, of_lp5523_leds_match);
518 #endif 518 #endif
519 519
520 static struct i2c_driver lp5523_driver = { 520 static struct i2c_driver lp5523_driver = {
521 .driver = { 521 .driver = {
522 .name = "lp5523x", 522 .name = "lp5523x",
523 .of_match_table = of_match_ptr(of_lp5523_leds_match), 523 .of_match_table = of_match_ptr(of_lp5523_leds_match),
524 }, 524 },
525 .probe = lp5523_probe, 525 .probe = lp5523_probe,
526 .remove = lp5523_remove, 526 .remove = lp5523_remove,
527 .id_table = lp5523_id, 527 .id_table = lp5523_id,
528 }; 528 };
529 529
530 module_i2c_driver(lp5523_driver); 530 module_i2c_driver(lp5523_driver);
531 531
532 MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>"); 532 MODULE_AUTHOR("Mathias Nyman <mathias.nyman@nokia.com>");
533 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 533 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
534 MODULE_DESCRIPTION("LP5523 LED engine"); 534 MODULE_DESCRIPTION("LP5523 LED engine");
535 MODULE_LICENSE("GPL"); 535 MODULE_LICENSE("GPL");
536 536
drivers/leds/leds-lp5562.c
1 /* 1 /*
2 * LP5562 LED driver 2 * LP5562 LED driver
3 * 3 *
4 * Copyright (C) 2013 Texas Instruments 4 * Copyright (C) 2013 Texas Instruments
5 * 5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13 #include <linux/delay.h> 13 #include <linux/delay.h>
14 #include <linux/firmware.h> 14 #include <linux/firmware.h>
15 #include <linux/i2c.h> 15 #include <linux/i2c.h>
16 #include <linux/init.h> 16 #include <linux/init.h>
17 #include <linux/leds.h> 17 #include <linux/leds.h>
18 #include <linux/module.h> 18 #include <linux/module.h>
19 #include <linux/mutex.h> 19 #include <linux/mutex.h>
20 #include <linux/platform_data/leds-lp55xx.h> 20 #include <linux/platform_data/leds-lp55xx.h>
21 #include <linux/slab.h> 21 #include <linux/slab.h>
22 22
23 #include "leds-lp55xx-common.h" 23 #include "leds-lp55xx-common.h"
24 24
25 #define LP5562_PROGRAM_LENGTH 32 25 #define LP5562_PROGRAM_LENGTH 32
26 #define LP5562_MAX_LEDS 4 26 #define LP5562_MAX_LEDS 4
27 27
28 /* ENABLE Register 00h */ 28 /* ENABLE Register 00h */
29 #define LP5562_REG_ENABLE 0x00 29 #define LP5562_REG_ENABLE 0x00
30 #define LP5562_EXEC_ENG1_M 0x30 30 #define LP5562_EXEC_ENG1_M 0x30
31 #define LP5562_EXEC_ENG2_M 0x0C 31 #define LP5562_EXEC_ENG2_M 0x0C
32 #define LP5562_EXEC_ENG3_M 0x03 32 #define LP5562_EXEC_ENG3_M 0x03
33 #define LP5562_EXEC_M 0x3F 33 #define LP5562_EXEC_M 0x3F
34 #define LP5562_MASTER_ENABLE 0x40 /* Chip master enable */ 34 #define LP5562_MASTER_ENABLE 0x40 /* Chip master enable */
35 #define LP5562_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */ 35 #define LP5562_LOGARITHMIC_PWM 0x80 /* Logarithmic PWM adjustment */
36 #define LP5562_EXEC_RUN 0x2A 36 #define LP5562_EXEC_RUN 0x2A
37 #define LP5562_ENABLE_DEFAULT \ 37 #define LP5562_ENABLE_DEFAULT \
38 (LP5562_MASTER_ENABLE | LP5562_LOGARITHMIC_PWM) 38 (LP5562_MASTER_ENABLE | LP5562_LOGARITHMIC_PWM)
39 #define LP5562_ENABLE_RUN_PROGRAM \ 39 #define LP5562_ENABLE_RUN_PROGRAM \
40 (LP5562_ENABLE_DEFAULT | LP5562_EXEC_RUN) 40 (LP5562_ENABLE_DEFAULT | LP5562_EXEC_RUN)
41 41
42 /* OPMODE Register 01h */ 42 /* OPMODE Register 01h */
43 #define LP5562_REG_OP_MODE 0x01 43 #define LP5562_REG_OP_MODE 0x01
44 #define LP5562_MODE_ENG1_M 0x30 44 #define LP5562_MODE_ENG1_M 0x30
45 #define LP5562_MODE_ENG2_M 0x0C 45 #define LP5562_MODE_ENG2_M 0x0C
46 #define LP5562_MODE_ENG3_M 0x03 46 #define LP5562_MODE_ENG3_M 0x03
47 #define LP5562_LOAD_ENG1 0x10 47 #define LP5562_LOAD_ENG1 0x10
48 #define LP5562_LOAD_ENG2 0x04 48 #define LP5562_LOAD_ENG2 0x04
49 #define LP5562_LOAD_ENG3 0x01 49 #define LP5562_LOAD_ENG3 0x01
50 #define LP5562_RUN_ENG1 0x20 50 #define LP5562_RUN_ENG1 0x20
51 #define LP5562_RUN_ENG2 0x08 51 #define LP5562_RUN_ENG2 0x08
52 #define LP5562_RUN_ENG3 0x02 52 #define LP5562_RUN_ENG3 0x02
53 #define LP5562_ENG1_IS_LOADING(mode) \ 53 #define LP5562_ENG1_IS_LOADING(mode) \
54 ((mode & LP5562_MODE_ENG1_M) == LP5562_LOAD_ENG1) 54 ((mode & LP5562_MODE_ENG1_M) == LP5562_LOAD_ENG1)
55 #define LP5562_ENG2_IS_LOADING(mode) \ 55 #define LP5562_ENG2_IS_LOADING(mode) \
56 ((mode & LP5562_MODE_ENG2_M) == LP5562_LOAD_ENG2) 56 ((mode & LP5562_MODE_ENG2_M) == LP5562_LOAD_ENG2)
57 #define LP5562_ENG3_IS_LOADING(mode) \ 57 #define LP5562_ENG3_IS_LOADING(mode) \
58 ((mode & LP5562_MODE_ENG3_M) == LP5562_LOAD_ENG3) 58 ((mode & LP5562_MODE_ENG3_M) == LP5562_LOAD_ENG3)
59 59
60 /* BRIGHTNESS Registers */ 60 /* BRIGHTNESS Registers */
61 #define LP5562_REG_R_PWM 0x04 61 #define LP5562_REG_R_PWM 0x04
62 #define LP5562_REG_G_PWM 0x03 62 #define LP5562_REG_G_PWM 0x03
63 #define LP5562_REG_B_PWM 0x02 63 #define LP5562_REG_B_PWM 0x02
64 #define LP5562_REG_W_PWM 0x0E 64 #define LP5562_REG_W_PWM 0x0E
65 65
66 /* CURRENT Registers */ 66 /* CURRENT Registers */
67 #define LP5562_REG_R_CURRENT 0x07 67 #define LP5562_REG_R_CURRENT 0x07
68 #define LP5562_REG_G_CURRENT 0x06 68 #define LP5562_REG_G_CURRENT 0x06
69 #define LP5562_REG_B_CURRENT 0x05 69 #define LP5562_REG_B_CURRENT 0x05
70 #define LP5562_REG_W_CURRENT 0x0F 70 #define LP5562_REG_W_CURRENT 0x0F
71 71
72 /* CONFIG Register 08h */ 72 /* CONFIG Register 08h */
73 #define LP5562_REG_CONFIG 0x08 73 #define LP5562_REG_CONFIG 0x08
74 #define LP5562_PWM_HF 0x40 74 #define LP5562_PWM_HF 0x40
75 #define LP5562_PWRSAVE_EN 0x20 75 #define LP5562_PWRSAVE_EN 0x20
76 #define LP5562_CLK_INT 0x01 /* Internal clock */ 76 #define LP5562_CLK_INT 0x01 /* Internal clock */
77 #define LP5562_DEFAULT_CFG (LP5562_PWM_HF | LP5562_PWRSAVE_EN) 77 #define LP5562_DEFAULT_CFG (LP5562_PWM_HF | LP5562_PWRSAVE_EN)
78 78
79 /* RESET Register 0Dh */ 79 /* RESET Register 0Dh */
80 #define LP5562_REG_RESET 0x0D 80 #define LP5562_REG_RESET 0x0D
81 #define LP5562_RESET 0xFF 81 #define LP5562_RESET 0xFF
82 82
83 /* PROGRAM ENGINE Registers */ 83 /* PROGRAM ENGINE Registers */
84 #define LP5562_REG_PROG_MEM_ENG1 0x10 84 #define LP5562_REG_PROG_MEM_ENG1 0x10
85 #define LP5562_REG_PROG_MEM_ENG2 0x30 85 #define LP5562_REG_PROG_MEM_ENG2 0x30
86 #define LP5562_REG_PROG_MEM_ENG3 0x50 86 #define LP5562_REG_PROG_MEM_ENG3 0x50
87 87
88 /* LEDMAP Register 70h */ 88 /* LEDMAP Register 70h */
89 #define LP5562_REG_ENG_SEL 0x70 89 #define LP5562_REG_ENG_SEL 0x70
90 #define LP5562_ENG_SEL_PWM 0 90 #define LP5562_ENG_SEL_PWM 0
91 #define LP5562_ENG_FOR_RGB_M 0x3F 91 #define LP5562_ENG_FOR_RGB_M 0x3F
92 #define LP5562_ENG_SEL_RGB 0x1B /* R:ENG1, G:ENG2, B:ENG3 */ 92 #define LP5562_ENG_SEL_RGB 0x1B /* R:ENG1, G:ENG2, B:ENG3 */
93 #define LP5562_ENG_FOR_W_M 0xC0 93 #define LP5562_ENG_FOR_W_M 0xC0
94 #define LP5562_ENG1_FOR_W 0x40 /* W:ENG1 */ 94 #define LP5562_ENG1_FOR_W 0x40 /* W:ENG1 */
95 #define LP5562_ENG2_FOR_W 0x80 /* W:ENG2 */ 95 #define LP5562_ENG2_FOR_W 0x80 /* W:ENG2 */
96 #define LP5562_ENG3_FOR_W 0xC0 /* W:ENG3 */ 96 #define LP5562_ENG3_FOR_W 0xC0 /* W:ENG3 */
97 97
98 /* Program Commands */ 98 /* Program Commands */
99 #define LP5562_CMD_DISABLE 0x00 99 #define LP5562_CMD_DISABLE 0x00
100 #define LP5562_CMD_LOAD 0x15 100 #define LP5562_CMD_LOAD 0x15
101 #define LP5562_CMD_RUN 0x2A 101 #define LP5562_CMD_RUN 0x2A
102 #define LP5562_CMD_DIRECT 0x3F 102 #define LP5562_CMD_DIRECT 0x3F
103 #define LP5562_PATTERN_OFF 0 103 #define LP5562_PATTERN_OFF 0
104 104
105 static inline void lp5562_wait_opmode_done(void) 105 static inline void lp5562_wait_opmode_done(void)
106 { 106 {
107 /* operation mode change needs to be longer than 153 us */ 107 /* operation mode change needs to be longer than 153 us */
108 usleep_range(200, 300); 108 usleep_range(200, 300);
109 } 109 }
110 110
111 static inline void lp5562_wait_enable_done(void) 111 static inline void lp5562_wait_enable_done(void)
112 { 112 {
113 /* it takes more 488 us to update ENABLE register */ 113 /* it takes more 488 us to update ENABLE register */
114 usleep_range(500, 600); 114 usleep_range(500, 600);
115 } 115 }
116 116
117 static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current) 117 static void lp5562_set_led_current(struct lp55xx_led *led, u8 led_current)
118 { 118 {
119 u8 addr[] = { 119 u8 addr[] = {
120 LP5562_REG_R_CURRENT, 120 LP5562_REG_R_CURRENT,
121 LP5562_REG_G_CURRENT, 121 LP5562_REG_G_CURRENT,
122 LP5562_REG_B_CURRENT, 122 LP5562_REG_B_CURRENT,
123 LP5562_REG_W_CURRENT, 123 LP5562_REG_W_CURRENT,
124 }; 124 };
125 125
126 led->led_current = led_current; 126 led->led_current = led_current;
127 lp55xx_write(led->chip, addr[led->chan_nr], led_current); 127 lp55xx_write(led->chip, addr[led->chan_nr], led_current);
128 } 128 }
129 129
130 static void lp5562_load_engine(struct lp55xx_chip *chip) 130 static void lp5562_load_engine(struct lp55xx_chip *chip)
131 { 131 {
132 enum lp55xx_engine_index idx = chip->engine_idx; 132 enum lp55xx_engine_index idx = chip->engine_idx;
133 u8 mask[] = { 133 u8 mask[] = {
134 [LP55XX_ENGINE_1] = LP5562_MODE_ENG1_M, 134 [LP55XX_ENGINE_1] = LP5562_MODE_ENG1_M,
135 [LP55XX_ENGINE_2] = LP5562_MODE_ENG2_M, 135 [LP55XX_ENGINE_2] = LP5562_MODE_ENG2_M,
136 [LP55XX_ENGINE_3] = LP5562_MODE_ENG3_M, 136 [LP55XX_ENGINE_3] = LP5562_MODE_ENG3_M,
137 }; 137 };
138 138
139 u8 val[] = { 139 u8 val[] = {
140 [LP55XX_ENGINE_1] = LP5562_LOAD_ENG1, 140 [LP55XX_ENGINE_1] = LP5562_LOAD_ENG1,
141 [LP55XX_ENGINE_2] = LP5562_LOAD_ENG2, 141 [LP55XX_ENGINE_2] = LP5562_LOAD_ENG2,
142 [LP55XX_ENGINE_3] = LP5562_LOAD_ENG3, 142 [LP55XX_ENGINE_3] = LP5562_LOAD_ENG3,
143 }; 143 };
144 144
145 lp55xx_update_bits(chip, LP5562_REG_OP_MODE, mask[idx], val[idx]); 145 lp55xx_update_bits(chip, LP5562_REG_OP_MODE, mask[idx], val[idx]);
146 146
147 lp5562_wait_opmode_done(); 147 lp5562_wait_opmode_done();
148 } 148 }
149 149
150 static void lp5562_stop_engine(struct lp55xx_chip *chip) 150 static void lp5562_stop_engine(struct lp55xx_chip *chip)
151 { 151 {
152 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DISABLE); 152 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DISABLE);
153 lp5562_wait_opmode_done(); 153 lp5562_wait_opmode_done();
154 } 154 }
155 155
156 static void lp5562_run_engine(struct lp55xx_chip *chip, bool start) 156 static void lp5562_run_engine(struct lp55xx_chip *chip, bool start)
157 { 157 {
158 int ret; 158 int ret;
159 u8 mode; 159 u8 mode;
160 u8 exec; 160 u8 exec;
161 161
162 /* stop engine */ 162 /* stop engine */
163 if (!start) { 163 if (!start) {
164 lp55xx_write(chip, LP5562_REG_ENABLE, LP5562_ENABLE_DEFAULT); 164 lp55xx_write(chip, LP5562_REG_ENABLE, LP5562_ENABLE_DEFAULT);
165 lp5562_wait_enable_done(); 165 lp5562_wait_enable_done();
166 lp5562_stop_engine(chip); 166 lp5562_stop_engine(chip);
167 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM); 167 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM);
168 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT); 168 lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT);
169 lp5562_wait_opmode_done(); 169 lp5562_wait_opmode_done();
170 return; 170 return;
171 } 171 }
172 172
173 /* 173 /*
174 * To run the engine, 174 * To run the engine,
175 * operation mode and enable register should updated at the same time 175 * operation mode and enable register should updated at the same time
176 */ 176 */
177 177
178 ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode); 178 ret = lp55xx_read(chip, LP5562_REG_OP_MODE, &mode);
179 if (ret) 179 if (ret)
180 return; 180 return;
181 181
182 ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec); 182 ret = lp55xx_read(chip, LP5562_REG_ENABLE, &exec);
183 if (ret) 183 if (ret)
184 return; 184 return;
185 185
186 /* change operation mode to RUN only when each engine is loading */ 186 /* change operation mode to RUN only when each engine is loading */
187 if (LP5562_ENG1_IS_LOADING(mode)) { 187 if (LP5562_ENG1_IS_LOADING(mode)) {
188 mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1; 188 mode = (mode & ~LP5562_MODE_ENG1_M) | LP5562_RUN_ENG1;
189 exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1; 189 exec = (exec & ~LP5562_EXEC_ENG1_M) | LP5562_RUN_ENG1;
190 } 190 }
191 191
192 if (LP5562_ENG2_IS_LOADING(mode)) { 192 if (LP5562_ENG2_IS_LOADING(mode)) {
193 mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2; 193 mode = (mode & ~LP5562_MODE_ENG2_M) | LP5562_RUN_ENG2;
194 exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2; 194 exec = (exec & ~LP5562_EXEC_ENG2_M) | LP5562_RUN_ENG2;
195 } 195 }
196 196
197 if (LP5562_ENG3_IS_LOADING(mode)) { 197 if (LP5562_ENG3_IS_LOADING(mode)) {
198 mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3; 198 mode = (mode & ~LP5562_MODE_ENG3_M) | LP5562_RUN_ENG3;
199 exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3; 199 exec = (exec & ~LP5562_EXEC_ENG3_M) | LP5562_RUN_ENG3;
200 } 200 }
201 201
202 lp55xx_write(chip, LP5562_REG_OP_MODE, mode); 202 lp55xx_write(chip, LP5562_REG_OP_MODE, mode);
203 lp5562_wait_opmode_done(); 203 lp5562_wait_opmode_done();
204 204
205 lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec); 205 lp55xx_update_bits(chip, LP5562_REG_ENABLE, LP5562_EXEC_M, exec);
206 lp5562_wait_enable_done(); 206 lp5562_wait_enable_done();
207 } 207 }
208 208
209 static int lp5562_update_firmware(struct lp55xx_chip *chip, 209 static int lp5562_update_firmware(struct lp55xx_chip *chip,
210 const u8 *data, size_t size) 210 const u8 *data, size_t size)
211 { 211 {
212 enum lp55xx_engine_index idx = chip->engine_idx; 212 enum lp55xx_engine_index idx = chip->engine_idx;
213 u8 pattern[LP5562_PROGRAM_LENGTH] = {0}; 213 u8 pattern[LP5562_PROGRAM_LENGTH] = {0};
214 u8 addr[] = { 214 u8 addr[] = {
215 [LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1, 215 [LP55XX_ENGINE_1] = LP5562_REG_PROG_MEM_ENG1,
216 [LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2, 216 [LP55XX_ENGINE_2] = LP5562_REG_PROG_MEM_ENG2,
217 [LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3, 217 [LP55XX_ENGINE_3] = LP5562_REG_PROG_MEM_ENG3,
218 }; 218 };
219 unsigned cmd; 219 unsigned cmd;
220 char c[3]; 220 char c[3];
221 int program_size; 221 int program_size;
222 int nrchars; 222 int nrchars;
223 int offset = 0; 223 int offset = 0;
224 int ret; 224 int ret;
225 int i; 225 int i;
226 226
227 /* clear program memory before updating */ 227 /* clear program memory before updating */
228 for (i = 0; i < LP5562_PROGRAM_LENGTH; i++) 228 for (i = 0; i < LP5562_PROGRAM_LENGTH; i++)
229 lp55xx_write(chip, addr[idx] + i, 0); 229 lp55xx_write(chip, addr[idx] + i, 0);
230 230
231 i = 0; 231 i = 0;
232 while ((offset < size - 1) && (i < LP5562_PROGRAM_LENGTH)) { 232 while ((offset < size - 1) && (i < LP5562_PROGRAM_LENGTH)) {
233 /* separate sscanfs because length is working only for %s */ 233 /* separate sscanfs because length is working only for %s */
234 ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 234 ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
235 if (ret != 1) 235 if (ret != 1)
236 goto err; 236 goto err;
237 237
238 ret = sscanf(c, "%2x", &cmd); 238 ret = sscanf(c, "%2x", &cmd);
239 if (ret != 1) 239 if (ret != 1)
240 goto err; 240 goto err;
241 241
242 pattern[i] = (u8)cmd; 242 pattern[i] = (u8)cmd;
243 offset += nrchars; 243 offset += nrchars;
244 i++; 244 i++;
245 } 245 }
246 246
247 /* Each instruction is 16bit long. Check that length is even */ 247 /* Each instruction is 16bit long. Check that length is even */
248 if (i % 2) 248 if (i % 2)
249 goto err; 249 goto err;
250 250
251 program_size = i; 251 program_size = i;
252 for (i = 0; i < program_size; i++) 252 for (i = 0; i < program_size; i++)
253 lp55xx_write(chip, addr[idx] + i, pattern[i]); 253 lp55xx_write(chip, addr[idx] + i, pattern[i]);
254 254
255 return 0; 255 return 0;
256 256
257 err: 257 err:
258 dev_err(&chip->cl->dev, "wrong pattern format\n"); 258 dev_err(&chip->cl->dev, "wrong pattern format\n");
259 return -EINVAL; 259 return -EINVAL;
260 } 260 }
261 261
262 static void lp5562_firmware_loaded(struct lp55xx_chip *chip) 262 static void lp5562_firmware_loaded(struct lp55xx_chip *chip)
263 { 263 {
264 const struct firmware *fw = chip->fw; 264 const struct firmware *fw = chip->fw;
265 265
266 if (fw->size > LP5562_PROGRAM_LENGTH) { 266 if (fw->size > LP5562_PROGRAM_LENGTH) {
267 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 267 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
268 fw->size); 268 fw->size);
269 return; 269 return;
270 } 270 }
271 271
272 /* 272 /*
273 * Program momery sequence 273 * Program momery sequence
274 * 1) set engine mode to "LOAD" 274 * 1) set engine mode to "LOAD"
275 * 2) write firmware data into program memory 275 * 2) write firmware data into program memory
276 */ 276 */
277 277
278 lp5562_load_engine(chip); 278 lp5562_load_engine(chip);
279 lp5562_update_firmware(chip, fw->data, fw->size); 279 lp5562_update_firmware(chip, fw->data, fw->size);
280 } 280 }
281 281
282 static int lp5562_post_init_device(struct lp55xx_chip *chip) 282 static int lp5562_post_init_device(struct lp55xx_chip *chip)
283 { 283 {
284 int ret; 284 int ret;
285 u8 cfg = LP5562_DEFAULT_CFG; 285 u8 cfg = LP5562_DEFAULT_CFG;
286 286
287 /* Set all PWMs to direct control mode */ 287 /* Set all PWMs to direct control mode */
288 ret = lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT); 288 ret = lp55xx_write(chip, LP5562_REG_OP_MODE, LP5562_CMD_DIRECT);
289 if (ret) 289 if (ret)
290 return ret; 290 return ret;
291 291
292 lp5562_wait_opmode_done(); 292 lp5562_wait_opmode_done();
293 293
294 /* Update configuration for the clock setting */ 294 /* Update configuration for the clock setting */
295 if (!lp55xx_is_extclk_used(chip)) 295 if (!lp55xx_is_extclk_used(chip))
296 cfg |= LP5562_CLK_INT; 296 cfg |= LP5562_CLK_INT;
297 297
298 ret = lp55xx_write(chip, LP5562_REG_CONFIG, cfg); 298 ret = lp55xx_write(chip, LP5562_REG_CONFIG, cfg);
299 if (ret) 299 if (ret)
300 return ret; 300 return ret;
301 301
302 /* Initialize all channels PWM to zero -> leds off */ 302 /* Initialize all channels PWM to zero -> leds off */
303 lp55xx_write(chip, LP5562_REG_R_PWM, 0); 303 lp55xx_write(chip, LP5562_REG_R_PWM, 0);
304 lp55xx_write(chip, LP5562_REG_G_PWM, 0); 304 lp55xx_write(chip, LP5562_REG_G_PWM, 0);
305 lp55xx_write(chip, LP5562_REG_B_PWM, 0); 305 lp55xx_write(chip, LP5562_REG_B_PWM, 0);
306 lp55xx_write(chip, LP5562_REG_W_PWM, 0); 306 lp55xx_write(chip, LP5562_REG_W_PWM, 0);
307 307
308 /* Set LED map as register PWM by default */ 308 /* Set LED map as register PWM by default */
309 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM); 309 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_PWM);
310 310
311 return 0; 311 return 0;
312 } 312 }
313 313
314 static void lp5562_led_brightness_work(struct work_struct *work) 314 static void lp5562_led_brightness_work(struct work_struct *work)
315 { 315 {
316 struct lp55xx_led *led = container_of(work, struct lp55xx_led, 316 struct lp55xx_led *led = container_of(work, struct lp55xx_led,
317 brightness_work); 317 brightness_work);
318 struct lp55xx_chip *chip = led->chip; 318 struct lp55xx_chip *chip = led->chip;
319 u8 addr[] = { 319 u8 addr[] = {
320 LP5562_REG_R_PWM, 320 LP5562_REG_R_PWM,
321 LP5562_REG_G_PWM, 321 LP5562_REG_G_PWM,
322 LP5562_REG_B_PWM, 322 LP5562_REG_B_PWM,
323 LP5562_REG_W_PWM, 323 LP5562_REG_W_PWM,
324 }; 324 };
325 325
326 mutex_lock(&chip->lock); 326 mutex_lock(&chip->lock);
327 lp55xx_write(chip, addr[led->chan_nr], led->brightness); 327 lp55xx_write(chip, addr[led->chan_nr], led->brightness);
328 mutex_unlock(&chip->lock); 328 mutex_unlock(&chip->lock);
329 } 329 }
330 330
331 static void lp5562_write_program_memory(struct lp55xx_chip *chip, 331 static void lp5562_write_program_memory(struct lp55xx_chip *chip,
332 u8 base, const u8 *rgb, int size) 332 u8 base, const u8 *rgb, int size)
333 { 333 {
334 int i; 334 int i;
335 335
336 if (!rgb || size <= 0) 336 if (!rgb || size <= 0)
337 return; 337 return;
338 338
339 for (i = 0; i < size; i++) 339 for (i = 0; i < size; i++)
340 lp55xx_write(chip, base + i, *(rgb + i)); 340 lp55xx_write(chip, base + i, *(rgb + i));
341 341
342 lp55xx_write(chip, base + i, 0); 342 lp55xx_write(chip, base + i, 0);
343 lp55xx_write(chip, base + i + 1, 0); 343 lp55xx_write(chip, base + i + 1, 0);
344 } 344 }
345 345
346 /* check the size of program count */ 346 /* check the size of program count */
347 static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn) 347 static inline bool _is_pc_overflow(struct lp55xx_predef_pattern *ptn)
348 { 348 {
349 return (ptn->size_r >= LP5562_PROGRAM_LENGTH || 349 return (ptn->size_r >= LP5562_PROGRAM_LENGTH ||
350 ptn->size_g >= LP5562_PROGRAM_LENGTH || 350 ptn->size_g >= LP5562_PROGRAM_LENGTH ||
351 ptn->size_b >= LP5562_PROGRAM_LENGTH); 351 ptn->size_b >= LP5562_PROGRAM_LENGTH);
352 } 352 }
353 353
354 static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode) 354 static int lp5562_run_predef_led_pattern(struct lp55xx_chip *chip, int mode)
355 { 355 {
356 struct lp55xx_predef_pattern *ptn; 356 struct lp55xx_predef_pattern *ptn;
357 int i; 357 int i;
358 358
359 if (mode == LP5562_PATTERN_OFF) { 359 if (mode == LP5562_PATTERN_OFF) {
360 lp5562_run_engine(chip, false); 360 lp5562_run_engine(chip, false);
361 return 0; 361 return 0;
362 } 362 }
363 363
364 ptn = chip->pdata->patterns + (mode - 1); 364 ptn = chip->pdata->patterns + (mode - 1);
365 if (!ptn || _is_pc_overflow(ptn)) { 365 if (!ptn || _is_pc_overflow(ptn)) {
366 dev_err(&chip->cl->dev, "invalid pattern data\n"); 366 dev_err(&chip->cl->dev, "invalid pattern data\n");
367 return -EINVAL; 367 return -EINVAL;
368 } 368 }
369 369
370 lp5562_stop_engine(chip); 370 lp5562_stop_engine(chip);
371 371
372 /* Set LED map as RGB */ 372 /* Set LED map as RGB */
373 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_RGB); 373 lp55xx_write(chip, LP5562_REG_ENG_SEL, LP5562_ENG_SEL_RGB);
374 374
375 /* Load engines */ 375 /* Load engines */
376 for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) { 376 for (i = LP55XX_ENGINE_1; i <= LP55XX_ENGINE_3; i++) {
377 chip->engine_idx = i; 377 chip->engine_idx = i;
378 lp5562_load_engine(chip); 378 lp5562_load_engine(chip);
379 } 379 }
380 380
381 /* Clear program registers */ 381 /* Clear program registers */
382 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1, 0); 382 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1, 0);
383 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1 + 1, 0); 383 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG1 + 1, 0);
384 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2, 0); 384 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2, 0);
385 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2 + 1, 0); 385 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG2 + 1, 0);
386 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3, 0); 386 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3, 0);
387 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3 + 1, 0); 387 lp55xx_write(chip, LP5562_REG_PROG_MEM_ENG3 + 1, 0);
388 388
389 /* Program engines */ 389 /* Program engines */
390 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG1, 390 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG1,
391 ptn->r, ptn->size_r); 391 ptn->r, ptn->size_r);
392 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG2, 392 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG2,
393 ptn->g, ptn->size_g); 393 ptn->g, ptn->size_g);
394 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG3, 394 lp5562_write_program_memory(chip, LP5562_REG_PROG_MEM_ENG3,
395 ptn->b, ptn->size_b); 395 ptn->b, ptn->size_b);
396 396
397 /* Run engines */ 397 /* Run engines */
398 lp5562_run_engine(chip, true); 398 lp5562_run_engine(chip, true);
399 399
400 return 0; 400 return 0;
401 } 401 }
402 402
403 static ssize_t lp5562_store_pattern(struct device *dev, 403 static ssize_t lp5562_store_pattern(struct device *dev,
404 struct device_attribute *attr, 404 struct device_attribute *attr,
405 const char *buf, size_t len) 405 const char *buf, size_t len)
406 { 406 {
407 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 407 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
408 struct lp55xx_chip *chip = led->chip; 408 struct lp55xx_chip *chip = led->chip;
409 struct lp55xx_predef_pattern *ptn = chip->pdata->patterns; 409 struct lp55xx_predef_pattern *ptn = chip->pdata->patterns;
410 int num_patterns = chip->pdata->num_patterns; 410 int num_patterns = chip->pdata->num_patterns;
411 unsigned long mode; 411 unsigned long mode;
412 int ret; 412 int ret;
413 413
414 ret = kstrtoul(buf, 0, &mode); 414 ret = kstrtoul(buf, 0, &mode);
415 if (ret) 415 if (ret)
416 return ret; 416 return ret;
417 417
418 if (mode > num_patterns || !ptn) 418 if (mode > num_patterns || !ptn)
419 return -EINVAL; 419 return -EINVAL;
420 420
421 mutex_lock(&chip->lock); 421 mutex_lock(&chip->lock);
422 ret = lp5562_run_predef_led_pattern(chip, mode); 422 ret = lp5562_run_predef_led_pattern(chip, mode);
423 mutex_unlock(&chip->lock); 423 mutex_unlock(&chip->lock);
424 424
425 if (ret) 425 if (ret)
426 return ret; 426 return ret;
427 427
428 return len; 428 return len;
429 } 429 }
430 430
431 static ssize_t lp5562_store_engine_mux(struct device *dev, 431 static ssize_t lp5562_store_engine_mux(struct device *dev,
432 struct device_attribute *attr, 432 struct device_attribute *attr,
433 const char *buf, size_t len) 433 const char *buf, size_t len)
434 { 434 {
435 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev)); 435 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
436 struct lp55xx_chip *chip = led->chip; 436 struct lp55xx_chip *chip = led->chip;
437 u8 mask; 437 u8 mask;
438 u8 val; 438 u8 val;
439 439
440 /* LED map 440 /* LED map
441 * R ... Engine 1 (fixed) 441 * R ... Engine 1 (fixed)
442 * G ... Engine 2 (fixed) 442 * G ... Engine 2 (fixed)
443 * B ... Engine 3 (fixed) 443 * B ... Engine 3 (fixed)
444 * W ... Engine 1 or 2 or 3 444 * W ... Engine 1 or 2 or 3
445 */ 445 */
446 446
447 if (sysfs_streq(buf, "RGB")) { 447 if (sysfs_streq(buf, "RGB")) {
448 mask = LP5562_ENG_FOR_RGB_M; 448 mask = LP5562_ENG_FOR_RGB_M;
449 val = LP5562_ENG_SEL_RGB; 449 val = LP5562_ENG_SEL_RGB;
450 } else if (sysfs_streq(buf, "W")) { 450 } else if (sysfs_streq(buf, "W")) {
451 enum lp55xx_engine_index idx = chip->engine_idx; 451 enum lp55xx_engine_index idx = chip->engine_idx;
452 452
453 mask = LP5562_ENG_FOR_W_M; 453 mask = LP5562_ENG_FOR_W_M;
454 switch (idx) { 454 switch (idx) {
455 case LP55XX_ENGINE_1: 455 case LP55XX_ENGINE_1:
456 val = LP5562_ENG1_FOR_W; 456 val = LP5562_ENG1_FOR_W;
457 break; 457 break;
458 case LP55XX_ENGINE_2: 458 case LP55XX_ENGINE_2:
459 val = LP5562_ENG2_FOR_W; 459 val = LP5562_ENG2_FOR_W;
460 break; 460 break;
461 case LP55XX_ENGINE_3: 461 case LP55XX_ENGINE_3:
462 val = LP5562_ENG3_FOR_W; 462 val = LP5562_ENG3_FOR_W;
463 break; 463 break;
464 default: 464 default:
465 return -EINVAL; 465 return -EINVAL;
466 } 466 }
467 467
468 } else { 468 } else {
469 dev_err(dev, "choose RGB or W\n"); 469 dev_err(dev, "choose RGB or W\n");
470 return -EINVAL; 470 return -EINVAL;
471 } 471 }
472 472
473 mutex_lock(&chip->lock); 473 mutex_lock(&chip->lock);
474 lp55xx_update_bits(chip, LP5562_REG_ENG_SEL, mask, val); 474 lp55xx_update_bits(chip, LP5562_REG_ENG_SEL, mask, val);
475 mutex_unlock(&chip->lock); 475 mutex_unlock(&chip->lock);
476 476
477 return len; 477 return len;
478 } 478 }
479 479
480 static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, lp5562_store_pattern); 480 static DEVICE_ATTR(led_pattern, S_IWUSR, NULL, lp5562_store_pattern);
481 static DEVICE_ATTR(engine_mux, S_IWUSR, NULL, lp5562_store_engine_mux); 481 static DEVICE_ATTR(engine_mux, S_IWUSR, NULL, lp5562_store_engine_mux);
482 482
483 static struct attribute *lp5562_attributes[] = { 483 static struct attribute *lp5562_attributes[] = {
484 &dev_attr_led_pattern.attr, 484 &dev_attr_led_pattern.attr,
485 &dev_attr_engine_mux.attr, 485 &dev_attr_engine_mux.attr,
486 NULL, 486 NULL,
487 }; 487 };
488 488
489 static const struct attribute_group lp5562_group = { 489 static const struct attribute_group lp5562_group = {
490 .attrs = lp5562_attributes, 490 .attrs = lp5562_attributes,
491 }; 491 };
492 492
493 /* Chip specific configurations */ 493 /* Chip specific configurations */
494 static struct lp55xx_device_config lp5562_cfg = { 494 static struct lp55xx_device_config lp5562_cfg = {
495 .max_channel = LP5562_MAX_LEDS, 495 .max_channel = LP5562_MAX_LEDS,
496 .reset = { 496 .reset = {
497 .addr = LP5562_REG_RESET, 497 .addr = LP5562_REG_RESET,
498 .val = LP5562_RESET, 498 .val = LP5562_RESET,
499 }, 499 },
500 .enable = { 500 .enable = {
501 .addr = LP5562_REG_ENABLE, 501 .addr = LP5562_REG_ENABLE,
502 .val = LP5562_ENABLE_DEFAULT, 502 .val = LP5562_ENABLE_DEFAULT,
503 }, 503 },
504 .post_init_device = lp5562_post_init_device, 504 .post_init_device = lp5562_post_init_device,
505 .set_led_current = lp5562_set_led_current, 505 .set_led_current = lp5562_set_led_current,
506 .brightness_work_fn = lp5562_led_brightness_work, 506 .brightness_work_fn = lp5562_led_brightness_work,
507 .run_engine = lp5562_run_engine, 507 .run_engine = lp5562_run_engine,
508 .firmware_cb = lp5562_firmware_loaded, 508 .firmware_cb = lp5562_firmware_loaded,
509 .dev_attr_group = &lp5562_group, 509 .dev_attr_group = &lp5562_group,
510 }; 510 };
511 511
512 static int lp5562_probe(struct i2c_client *client, 512 static int lp5562_probe(struct i2c_client *client,
513 const struct i2c_device_id *id) 513 const struct i2c_device_id *id)
514 { 514 {
515 int ret; 515 int ret;
516 struct lp55xx_chip *chip; 516 struct lp55xx_chip *chip;
517 struct lp55xx_led *led; 517 struct lp55xx_led *led;
518 struct lp55xx_platform_data *pdata; 518 struct lp55xx_platform_data *pdata;
519 struct device_node *np = client->dev.of_node; 519 struct device_node *np = client->dev.of_node;
520 520
521 if (!client->dev.platform_data) { 521 if (!dev_get_platdata(&client->dev)) {
522 if (np) { 522 if (np) {
523 ret = lp55xx_of_populate_pdata(&client->dev, np); 523 ret = lp55xx_of_populate_pdata(&client->dev, np);
524 if (ret < 0) 524 if (ret < 0)
525 return ret; 525 return ret;
526 } else { 526 } else {
527 dev_err(&client->dev, "no platform data\n"); 527 dev_err(&client->dev, "no platform data\n");
528 return -EINVAL; 528 return -EINVAL;
529 } 529 }
530 } 530 }
531 pdata = client->dev.platform_data; 531 pdata = dev_get_platdata(&client->dev);
532 532
533 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 533 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
534 if (!chip) 534 if (!chip)
535 return -ENOMEM; 535 return -ENOMEM;
536 536
537 led = devm_kzalloc(&client->dev, 537 led = devm_kzalloc(&client->dev,
538 sizeof(*led) * pdata->num_channels, GFP_KERNEL); 538 sizeof(*led) * pdata->num_channels, GFP_KERNEL);
539 if (!led) 539 if (!led)
540 return -ENOMEM; 540 return -ENOMEM;
541 541
542 chip->cl = client; 542 chip->cl = client;
543 chip->pdata = pdata; 543 chip->pdata = pdata;
544 chip->cfg = &lp5562_cfg; 544 chip->cfg = &lp5562_cfg;
545 545
546 mutex_init(&chip->lock); 546 mutex_init(&chip->lock);
547 547
548 i2c_set_clientdata(client, led); 548 i2c_set_clientdata(client, led);
549 549
550 ret = lp55xx_init_device(chip); 550 ret = lp55xx_init_device(chip);
551 if (ret) 551 if (ret)
552 goto err_init; 552 goto err_init;
553 553
554 ret = lp55xx_register_leds(led, chip); 554 ret = lp55xx_register_leds(led, chip);
555 if (ret) 555 if (ret)
556 goto err_register_leds; 556 goto err_register_leds;
557 557
558 ret = lp55xx_register_sysfs(chip); 558 ret = lp55xx_register_sysfs(chip);
559 if (ret) { 559 if (ret) {
560 dev_err(&client->dev, "registering sysfs failed\n"); 560 dev_err(&client->dev, "registering sysfs failed\n");
561 goto err_register_sysfs; 561 goto err_register_sysfs;
562 } 562 }
563 563
564 return 0; 564 return 0;
565 565
566 err_register_sysfs: 566 err_register_sysfs:
567 lp55xx_unregister_leds(led, chip); 567 lp55xx_unregister_leds(led, chip);
568 err_register_leds: 568 err_register_leds:
569 lp55xx_deinit_device(chip); 569 lp55xx_deinit_device(chip);
570 err_init: 570 err_init:
571 return ret; 571 return ret;
572 } 572 }
573 573
574 static int lp5562_remove(struct i2c_client *client) 574 static int lp5562_remove(struct i2c_client *client)
575 { 575 {
576 struct lp55xx_led *led = i2c_get_clientdata(client); 576 struct lp55xx_led *led = i2c_get_clientdata(client);
577 struct lp55xx_chip *chip = led->chip; 577 struct lp55xx_chip *chip = led->chip;
578 578
579 lp5562_stop_engine(chip); 579 lp5562_stop_engine(chip);
580 580
581 lp55xx_unregister_sysfs(chip); 581 lp55xx_unregister_sysfs(chip);
582 lp55xx_unregister_leds(led, chip); 582 lp55xx_unregister_leds(led, chip);
583 lp55xx_deinit_device(chip); 583 lp55xx_deinit_device(chip);
584 584
585 return 0; 585 return 0;
586 } 586 }
587 587
588 static const struct i2c_device_id lp5562_id[] = { 588 static const struct i2c_device_id lp5562_id[] = {
589 { "lp5562", 0 }, 589 { "lp5562", 0 },
590 { } 590 { }
591 }; 591 };
592 MODULE_DEVICE_TABLE(i2c, lp5562_id); 592 MODULE_DEVICE_TABLE(i2c, lp5562_id);
593 593
594 #ifdef CONFIG_OF 594 #ifdef CONFIG_OF
595 static const struct of_device_id of_lp5562_leds_match[] = { 595 static const struct of_device_id of_lp5562_leds_match[] = {
596 { .compatible = "ti,lp5562", }, 596 { .compatible = "ti,lp5562", },
597 {}, 597 {},
598 }; 598 };
599 599
600 MODULE_DEVICE_TABLE(of, of_lp5562_leds_match); 600 MODULE_DEVICE_TABLE(of, of_lp5562_leds_match);
601 #endif 601 #endif
602 602
603 static struct i2c_driver lp5562_driver = { 603 static struct i2c_driver lp5562_driver = {
604 .driver = { 604 .driver = {
605 .name = "lp5562", 605 .name = "lp5562",
606 .of_match_table = of_match_ptr(of_lp5562_leds_match), 606 .of_match_table = of_match_ptr(of_lp5562_leds_match),
607 }, 607 },
608 .probe = lp5562_probe, 608 .probe = lp5562_probe,
609 .remove = lp5562_remove, 609 .remove = lp5562_remove,
610 .id_table = lp5562_id, 610 .id_table = lp5562_id,
611 }; 611 };
612 612
613 module_i2c_driver(lp5562_driver); 613 module_i2c_driver(lp5562_driver);
614 614
615 MODULE_DESCRIPTION("Texas Instruments LP5562 LED Driver"); 615 MODULE_DESCRIPTION("Texas Instruments LP5562 LED Driver");
616 MODULE_AUTHOR("Milo Kim"); 616 MODULE_AUTHOR("Milo Kim");
617 MODULE_LICENSE("GPL"); 617 MODULE_LICENSE("GPL");
618 618
drivers/leds/leds-lp8501.c
1 /* 1 /*
2 * TI LP8501 9 channel LED Driver 2 * TI LP8501 9 channel LED Driver
3 * 3 *
4 * Copyright (C) 2013 Texas Instruments 4 * Copyright (C) 2013 Texas Instruments
5 * 5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com> 6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License 9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation. 10 * version 2 as published by the Free Software Foundation.
11 * 11 *
12 */ 12 */
13 13
14 #include <linux/delay.h> 14 #include <linux/delay.h>
15 #include <linux/firmware.h> 15 #include <linux/firmware.h>
16 #include <linux/i2c.h> 16 #include <linux/i2c.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/leds.h> 18 #include <linux/leds.h>
19 #include <linux/module.h> 19 #include <linux/module.h>
20 #include <linux/mutex.h> 20 #include <linux/mutex.h>
21 #include <linux/platform_data/leds-lp55xx.h> 21 #include <linux/platform_data/leds-lp55xx.h>
22 #include <linux/slab.h> 22 #include <linux/slab.h>
23 23
24 #include "leds-lp55xx-common.h" 24 #include "leds-lp55xx-common.h"
25 25
26 #define LP8501_PROGRAM_LENGTH 32 26 #define LP8501_PROGRAM_LENGTH 32
27 #define LP8501_MAX_LEDS 9 27 #define LP8501_MAX_LEDS 9
28 28
29 /* Registers */ 29 /* Registers */
30 #define LP8501_REG_ENABLE 0x00 30 #define LP8501_REG_ENABLE 0x00
31 #define LP8501_ENABLE BIT(6) 31 #define LP8501_ENABLE BIT(6)
32 #define LP8501_EXEC_M 0x3F 32 #define LP8501_EXEC_M 0x3F
33 #define LP8501_EXEC_ENG1_M 0x30 33 #define LP8501_EXEC_ENG1_M 0x30
34 #define LP8501_EXEC_ENG2_M 0x0C 34 #define LP8501_EXEC_ENG2_M 0x0C
35 #define LP8501_EXEC_ENG3_M 0x03 35 #define LP8501_EXEC_ENG3_M 0x03
36 #define LP8501_RUN_ENG1 0x20 36 #define LP8501_RUN_ENG1 0x20
37 #define LP8501_RUN_ENG2 0x08 37 #define LP8501_RUN_ENG2 0x08
38 #define LP8501_RUN_ENG3 0x02 38 #define LP8501_RUN_ENG3 0x02
39 39
40 #define LP8501_REG_OP_MODE 0x01 40 #define LP8501_REG_OP_MODE 0x01
41 #define LP8501_MODE_ENG1_M 0x30 41 #define LP8501_MODE_ENG1_M 0x30
42 #define LP8501_MODE_ENG2_M 0x0C 42 #define LP8501_MODE_ENG2_M 0x0C
43 #define LP8501_MODE_ENG3_M 0x03 43 #define LP8501_MODE_ENG3_M 0x03
44 #define LP8501_LOAD_ENG1 0x10 44 #define LP8501_LOAD_ENG1 0x10
45 #define LP8501_LOAD_ENG2 0x04 45 #define LP8501_LOAD_ENG2 0x04
46 #define LP8501_LOAD_ENG3 0x01 46 #define LP8501_LOAD_ENG3 0x01
47 47
48 #define LP8501_REG_PWR_CONFIG 0x05 48 #define LP8501_REG_PWR_CONFIG 0x05
49 #define LP8501_PWR_CONFIG_M 0x03 49 #define LP8501_PWR_CONFIG_M 0x03
50 50
51 #define LP8501_REG_LED_PWM_BASE 0x16 51 #define LP8501_REG_LED_PWM_BASE 0x16
52 52
53 #define LP8501_REG_LED_CURRENT_BASE 0x26 53 #define LP8501_REG_LED_CURRENT_BASE 0x26
54 54
55 #define LP8501_REG_CONFIG 0x36 55 #define LP8501_REG_CONFIG 0x36
56 #define LP8501_PWM_PSAVE BIT(7) 56 #define LP8501_PWM_PSAVE BIT(7)
57 #define LP8501_AUTO_INC BIT(6) 57 #define LP8501_AUTO_INC BIT(6)
58 #define LP8501_PWR_SAVE BIT(5) 58 #define LP8501_PWR_SAVE BIT(5)
59 #define LP8501_CP_AUTO 0x18 59 #define LP8501_CP_AUTO 0x18
60 #define LP8501_INT_CLK BIT(0) 60 #define LP8501_INT_CLK BIT(0)
61 #define LP8501_DEFAULT_CFG \ 61 #define LP8501_DEFAULT_CFG \
62 (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE | LP8501_CP_AUTO) 62 (LP8501_PWM_PSAVE | LP8501_AUTO_INC | LP8501_PWR_SAVE | LP8501_CP_AUTO)
63 63
64 #define LP8501_REG_RESET 0x3D 64 #define LP8501_REG_RESET 0x3D
65 #define LP8501_RESET 0xFF 65 #define LP8501_RESET 0xFF
66 66
67 #define LP8501_REG_PROG_PAGE_SEL 0x4F 67 #define LP8501_REG_PROG_PAGE_SEL 0x4F
68 #define LP8501_PAGE_ENG1 0 68 #define LP8501_PAGE_ENG1 0
69 #define LP8501_PAGE_ENG2 1 69 #define LP8501_PAGE_ENG2 1
70 #define LP8501_PAGE_ENG3 2 70 #define LP8501_PAGE_ENG3 2
71 71
72 #define LP8501_REG_PROG_MEM 0x50 72 #define LP8501_REG_PROG_MEM 0x50
73 73
74 #define LP8501_ENG1_IS_LOADING(mode) \ 74 #define LP8501_ENG1_IS_LOADING(mode) \
75 ((mode & LP8501_MODE_ENG1_M) == LP8501_LOAD_ENG1) 75 ((mode & LP8501_MODE_ENG1_M) == LP8501_LOAD_ENG1)
76 #define LP8501_ENG2_IS_LOADING(mode) \ 76 #define LP8501_ENG2_IS_LOADING(mode) \
77 ((mode & LP8501_MODE_ENG2_M) == LP8501_LOAD_ENG2) 77 ((mode & LP8501_MODE_ENG2_M) == LP8501_LOAD_ENG2)
78 #define LP8501_ENG3_IS_LOADING(mode) \ 78 #define LP8501_ENG3_IS_LOADING(mode) \
79 ((mode & LP8501_MODE_ENG3_M) == LP8501_LOAD_ENG3) 79 ((mode & LP8501_MODE_ENG3_M) == LP8501_LOAD_ENG3)
80 80
81 static inline void lp8501_wait_opmode_done(void) 81 static inline void lp8501_wait_opmode_done(void)
82 { 82 {
83 usleep_range(1000, 2000); 83 usleep_range(1000, 2000);
84 } 84 }
85 85
86 static void lp8501_set_led_current(struct lp55xx_led *led, u8 led_current) 86 static void lp8501_set_led_current(struct lp55xx_led *led, u8 led_current)
87 { 87 {
88 led->led_current = led_current; 88 led->led_current = led_current;
89 lp55xx_write(led->chip, LP8501_REG_LED_CURRENT_BASE + led->chan_nr, 89 lp55xx_write(led->chip, LP8501_REG_LED_CURRENT_BASE + led->chan_nr,
90 led_current); 90 led_current);
91 } 91 }
92 92
93 static int lp8501_post_init_device(struct lp55xx_chip *chip) 93 static int lp8501_post_init_device(struct lp55xx_chip *chip)
94 { 94 {
95 int ret; 95 int ret;
96 u8 val = LP8501_DEFAULT_CFG; 96 u8 val = LP8501_DEFAULT_CFG;
97 97
98 ret = lp55xx_write(chip, LP8501_REG_ENABLE, LP8501_ENABLE); 98 ret = lp55xx_write(chip, LP8501_REG_ENABLE, LP8501_ENABLE);
99 if (ret) 99 if (ret)
100 return ret; 100 return ret;
101 101
102 /* Chip startup time is 500 us, 1 - 2 ms gives some margin */ 102 /* Chip startup time is 500 us, 1 - 2 ms gives some margin */
103 usleep_range(1000, 2000); 103 usleep_range(1000, 2000);
104 104
105 if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT) 105 if (chip->pdata->clock_mode != LP55XX_CLOCK_EXT)
106 val |= LP8501_INT_CLK; 106 val |= LP8501_INT_CLK;
107 107
108 ret = lp55xx_write(chip, LP8501_REG_CONFIG, val); 108 ret = lp55xx_write(chip, LP8501_REG_CONFIG, val);
109 if (ret) 109 if (ret)
110 return ret; 110 return ret;
111 111
112 /* Power selection for each output */ 112 /* Power selection for each output */
113 return lp55xx_update_bits(chip, LP8501_REG_PWR_CONFIG, 113 return lp55xx_update_bits(chip, LP8501_REG_PWR_CONFIG,
114 LP8501_PWR_CONFIG_M, chip->pdata->pwr_sel); 114 LP8501_PWR_CONFIG_M, chip->pdata->pwr_sel);
115 } 115 }
116 116
117 static void lp8501_load_engine(struct lp55xx_chip *chip) 117 static void lp8501_load_engine(struct lp55xx_chip *chip)
118 { 118 {
119 enum lp55xx_engine_index idx = chip->engine_idx; 119 enum lp55xx_engine_index idx = chip->engine_idx;
120 u8 mask[] = { 120 u8 mask[] = {
121 [LP55XX_ENGINE_1] = LP8501_MODE_ENG1_M, 121 [LP55XX_ENGINE_1] = LP8501_MODE_ENG1_M,
122 [LP55XX_ENGINE_2] = LP8501_MODE_ENG2_M, 122 [LP55XX_ENGINE_2] = LP8501_MODE_ENG2_M,
123 [LP55XX_ENGINE_3] = LP8501_MODE_ENG3_M, 123 [LP55XX_ENGINE_3] = LP8501_MODE_ENG3_M,
124 }; 124 };
125 125
126 u8 val[] = { 126 u8 val[] = {
127 [LP55XX_ENGINE_1] = LP8501_LOAD_ENG1, 127 [LP55XX_ENGINE_1] = LP8501_LOAD_ENG1,
128 [LP55XX_ENGINE_2] = LP8501_LOAD_ENG2, 128 [LP55XX_ENGINE_2] = LP8501_LOAD_ENG2,
129 [LP55XX_ENGINE_3] = LP8501_LOAD_ENG3, 129 [LP55XX_ENGINE_3] = LP8501_LOAD_ENG3,
130 }; 130 };
131 131
132 u8 page_sel[] = { 132 u8 page_sel[] = {
133 [LP55XX_ENGINE_1] = LP8501_PAGE_ENG1, 133 [LP55XX_ENGINE_1] = LP8501_PAGE_ENG1,
134 [LP55XX_ENGINE_2] = LP8501_PAGE_ENG2, 134 [LP55XX_ENGINE_2] = LP8501_PAGE_ENG2,
135 [LP55XX_ENGINE_3] = LP8501_PAGE_ENG3, 135 [LP55XX_ENGINE_3] = LP8501_PAGE_ENG3,
136 }; 136 };
137 137
138 lp55xx_update_bits(chip, LP8501_REG_OP_MODE, mask[idx], val[idx]); 138 lp55xx_update_bits(chip, LP8501_REG_OP_MODE, mask[idx], val[idx]);
139 139
140 lp8501_wait_opmode_done(); 140 lp8501_wait_opmode_done();
141 141
142 lp55xx_write(chip, LP8501_REG_PROG_PAGE_SEL, page_sel[idx]); 142 lp55xx_write(chip, LP8501_REG_PROG_PAGE_SEL, page_sel[idx]);
143 } 143 }
144 144
145 static void lp8501_stop_engine(struct lp55xx_chip *chip) 145 static void lp8501_stop_engine(struct lp55xx_chip *chip)
146 { 146 {
147 lp55xx_write(chip, LP8501_REG_OP_MODE, 0); 147 lp55xx_write(chip, LP8501_REG_OP_MODE, 0);
148 lp8501_wait_opmode_done(); 148 lp8501_wait_opmode_done();
149 } 149 }
150 150
151 static void lp8501_turn_off_channels(struct lp55xx_chip *chip) 151 static void lp8501_turn_off_channels(struct lp55xx_chip *chip)
152 { 152 {
153 int i; 153 int i;
154 154
155 for (i = 0; i < LP8501_MAX_LEDS; i++) 155 for (i = 0; i < LP8501_MAX_LEDS; i++)
156 lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + i, 0); 156 lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + i, 0);
157 } 157 }
158 158
159 static void lp8501_run_engine(struct lp55xx_chip *chip, bool start) 159 static void lp8501_run_engine(struct lp55xx_chip *chip, bool start)
160 { 160 {
161 int ret; 161 int ret;
162 u8 mode; 162 u8 mode;
163 u8 exec; 163 u8 exec;
164 164
165 /* stop engine */ 165 /* stop engine */
166 if (!start) { 166 if (!start) {
167 lp8501_stop_engine(chip); 167 lp8501_stop_engine(chip);
168 lp8501_turn_off_channels(chip); 168 lp8501_turn_off_channels(chip);
169 return; 169 return;
170 } 170 }
171 171
172 /* 172 /*
173 * To run the engine, 173 * To run the engine,
174 * operation mode and enable register should updated at the same time 174 * operation mode and enable register should updated at the same time
175 */ 175 */
176 176
177 ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode); 177 ret = lp55xx_read(chip, LP8501_REG_OP_MODE, &mode);
178 if (ret) 178 if (ret)
179 return; 179 return;
180 180
181 ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec); 181 ret = lp55xx_read(chip, LP8501_REG_ENABLE, &exec);
182 if (ret) 182 if (ret)
183 return; 183 return;
184 184
185 /* change operation mode to RUN only when each engine is loading */ 185 /* change operation mode to RUN only when each engine is loading */
186 if (LP8501_ENG1_IS_LOADING(mode)) { 186 if (LP8501_ENG1_IS_LOADING(mode)) {
187 mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1; 187 mode = (mode & ~LP8501_MODE_ENG1_M) | LP8501_RUN_ENG1;
188 exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1; 188 exec = (exec & ~LP8501_EXEC_ENG1_M) | LP8501_RUN_ENG1;
189 } 189 }
190 190
191 if (LP8501_ENG2_IS_LOADING(mode)) { 191 if (LP8501_ENG2_IS_LOADING(mode)) {
192 mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2; 192 mode = (mode & ~LP8501_MODE_ENG2_M) | LP8501_RUN_ENG2;
193 exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2; 193 exec = (exec & ~LP8501_EXEC_ENG2_M) | LP8501_RUN_ENG2;
194 } 194 }
195 195
196 if (LP8501_ENG3_IS_LOADING(mode)) { 196 if (LP8501_ENG3_IS_LOADING(mode)) {
197 mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3; 197 mode = (mode & ~LP8501_MODE_ENG3_M) | LP8501_RUN_ENG3;
198 exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3; 198 exec = (exec & ~LP8501_EXEC_ENG3_M) | LP8501_RUN_ENG3;
199 } 199 }
200 200
201 lp55xx_write(chip, LP8501_REG_OP_MODE, mode); 201 lp55xx_write(chip, LP8501_REG_OP_MODE, mode);
202 lp8501_wait_opmode_done(); 202 lp8501_wait_opmode_done();
203 203
204 lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec); 204 lp55xx_update_bits(chip, LP8501_REG_ENABLE, LP8501_EXEC_M, exec);
205 } 205 }
206 206
207 static int lp8501_update_program_memory(struct lp55xx_chip *chip, 207 static int lp8501_update_program_memory(struct lp55xx_chip *chip,
208 const u8 *data, size_t size) 208 const u8 *data, size_t size)
209 { 209 {
210 u8 pattern[LP8501_PROGRAM_LENGTH] = {0}; 210 u8 pattern[LP8501_PROGRAM_LENGTH] = {0};
211 unsigned cmd; 211 unsigned cmd;
212 char c[3]; 212 char c[3];
213 int update_size; 213 int update_size;
214 int nrchars; 214 int nrchars;
215 int offset = 0; 215 int offset = 0;
216 int ret; 216 int ret;
217 int i; 217 int i;
218 218
219 /* clear program memory before updating */ 219 /* clear program memory before updating */
220 for (i = 0; i < LP8501_PROGRAM_LENGTH; i++) 220 for (i = 0; i < LP8501_PROGRAM_LENGTH; i++)
221 lp55xx_write(chip, LP8501_REG_PROG_MEM + i, 0); 221 lp55xx_write(chip, LP8501_REG_PROG_MEM + i, 0);
222 222
223 i = 0; 223 i = 0;
224 while ((offset < size - 1) && (i < LP8501_PROGRAM_LENGTH)) { 224 while ((offset < size - 1) && (i < LP8501_PROGRAM_LENGTH)) {
225 /* separate sscanfs because length is working only for %s */ 225 /* separate sscanfs because length is working only for %s */
226 ret = sscanf(data + offset, "%2s%n ", c, &nrchars); 226 ret = sscanf(data + offset, "%2s%n ", c, &nrchars);
227 if (ret != 1) 227 if (ret != 1)
228 goto err; 228 goto err;
229 229
230 ret = sscanf(c, "%2x", &cmd); 230 ret = sscanf(c, "%2x", &cmd);
231 if (ret != 1) 231 if (ret != 1)
232 goto err; 232 goto err;
233 233
234 pattern[i] = (u8)cmd; 234 pattern[i] = (u8)cmd;
235 offset += nrchars; 235 offset += nrchars;
236 i++; 236 i++;
237 } 237 }
238 238
239 /* Each instruction is 16bit long. Check that length is even */ 239 /* Each instruction is 16bit long. Check that length is even */
240 if (i % 2) 240 if (i % 2)
241 goto err; 241 goto err;
242 242
243 update_size = i; 243 update_size = i;
244 for (i = 0; i < update_size; i++) 244 for (i = 0; i < update_size; i++)
245 lp55xx_write(chip, LP8501_REG_PROG_MEM + i, pattern[i]); 245 lp55xx_write(chip, LP8501_REG_PROG_MEM + i, pattern[i]);
246 246
247 return 0; 247 return 0;
248 248
249 err: 249 err:
250 dev_err(&chip->cl->dev, "wrong pattern format\n"); 250 dev_err(&chip->cl->dev, "wrong pattern format\n");
251 return -EINVAL; 251 return -EINVAL;
252 } 252 }
253 253
254 static void lp8501_firmware_loaded(struct lp55xx_chip *chip) 254 static void lp8501_firmware_loaded(struct lp55xx_chip *chip)
255 { 255 {
256 const struct firmware *fw = chip->fw; 256 const struct firmware *fw = chip->fw;
257 257
258 if (fw->size > LP8501_PROGRAM_LENGTH) { 258 if (fw->size > LP8501_PROGRAM_LENGTH) {
259 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n", 259 dev_err(&chip->cl->dev, "firmware data size overflow: %zu\n",
260 fw->size); 260 fw->size);
261 return; 261 return;
262 } 262 }
263 263
264 /* 264 /*
265 * Program momery sequence 265 * Program momery sequence
266 * 1) set engine mode to "LOAD" 266 * 1) set engine mode to "LOAD"
267 * 2) write firmware data into program memory 267 * 2) write firmware data into program memory
268 */ 268 */
269 269
270 lp8501_load_engine(chip); 270 lp8501_load_engine(chip);
271 lp8501_update_program_memory(chip, fw->data, fw->size); 271 lp8501_update_program_memory(chip, fw->data, fw->size);
272 } 272 }
273 273
274 static void lp8501_led_brightness_work(struct work_struct *work) 274 static void lp8501_led_brightness_work(struct work_struct *work)
275 { 275 {
276 struct lp55xx_led *led = container_of(work, struct lp55xx_led, 276 struct lp55xx_led *led = container_of(work, struct lp55xx_led,
277 brightness_work); 277 brightness_work);
278 struct lp55xx_chip *chip = led->chip; 278 struct lp55xx_chip *chip = led->chip;
279 279
280 mutex_lock(&chip->lock); 280 mutex_lock(&chip->lock);
281 lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + led->chan_nr, 281 lp55xx_write(chip, LP8501_REG_LED_PWM_BASE + led->chan_nr,
282 led->brightness); 282 led->brightness);
283 mutex_unlock(&chip->lock); 283 mutex_unlock(&chip->lock);
284 } 284 }
285 285
286 /* Chip specific configurations */ 286 /* Chip specific configurations */
287 static struct lp55xx_device_config lp8501_cfg = { 287 static struct lp55xx_device_config lp8501_cfg = {
288 .reset = { 288 .reset = {
289 .addr = LP8501_REG_RESET, 289 .addr = LP8501_REG_RESET,
290 .val = LP8501_RESET, 290 .val = LP8501_RESET,
291 }, 291 },
292 .enable = { 292 .enable = {
293 .addr = LP8501_REG_ENABLE, 293 .addr = LP8501_REG_ENABLE,
294 .val = LP8501_ENABLE, 294 .val = LP8501_ENABLE,
295 }, 295 },
296 .max_channel = LP8501_MAX_LEDS, 296 .max_channel = LP8501_MAX_LEDS,
297 .post_init_device = lp8501_post_init_device, 297 .post_init_device = lp8501_post_init_device,
298 .brightness_work_fn = lp8501_led_brightness_work, 298 .brightness_work_fn = lp8501_led_brightness_work,
299 .set_led_current = lp8501_set_led_current, 299 .set_led_current = lp8501_set_led_current,
300 .firmware_cb = lp8501_firmware_loaded, 300 .firmware_cb = lp8501_firmware_loaded,
301 .run_engine = lp8501_run_engine, 301 .run_engine = lp8501_run_engine,
302 }; 302 };
303 303
304 static int lp8501_probe(struct i2c_client *client, 304 static int lp8501_probe(struct i2c_client *client,
305 const struct i2c_device_id *id) 305 const struct i2c_device_id *id)
306 { 306 {
307 int ret; 307 int ret;
308 struct lp55xx_chip *chip; 308 struct lp55xx_chip *chip;
309 struct lp55xx_led *led; 309 struct lp55xx_led *led;
310 struct lp55xx_platform_data *pdata; 310 struct lp55xx_platform_data *pdata;
311 struct device_node *np = client->dev.of_node; 311 struct device_node *np = client->dev.of_node;
312 312
313 if (!client->dev.platform_data) { 313 if (!dev_get_platdata(&client->dev)) {
314 if (np) { 314 if (np) {
315 ret = lp55xx_of_populate_pdata(&client->dev, np); 315 ret = lp55xx_of_populate_pdata(&client->dev, np);
316 if (ret < 0) 316 if (ret < 0)
317 return ret; 317 return ret;
318 } else { 318 } else {
319 dev_err(&client->dev, "no platform data\n"); 319 dev_err(&client->dev, "no platform data\n");
320 return -EINVAL; 320 return -EINVAL;
321 } 321 }
322 } 322 }
323 pdata = client->dev.platform_data; 323 pdata = dev_get_platdata(&client->dev);
324 324
325 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL); 325 chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
326 if (!chip) 326 if (!chip)
327 return -ENOMEM; 327 return -ENOMEM;
328 328
329 led = devm_kzalloc(&client->dev, 329 led = devm_kzalloc(&client->dev,
330 sizeof(*led) * pdata->num_channels, GFP_KERNEL); 330 sizeof(*led) * pdata->num_channels, GFP_KERNEL);
331 if (!led) 331 if (!led)
332 return -ENOMEM; 332 return -ENOMEM;
333 333
334 chip->cl = client; 334 chip->cl = client;
335 chip->pdata = pdata; 335 chip->pdata = pdata;
336 chip->cfg = &lp8501_cfg; 336 chip->cfg = &lp8501_cfg;
337 337
338 mutex_init(&chip->lock); 338 mutex_init(&chip->lock);
339 339
340 i2c_set_clientdata(client, led); 340 i2c_set_clientdata(client, led);
341 341
342 ret = lp55xx_init_device(chip); 342 ret = lp55xx_init_device(chip);
343 if (ret) 343 if (ret)
344 goto err_init; 344 goto err_init;
345 345
346 dev_info(&client->dev, "%s Programmable led chip found\n", id->name); 346 dev_info(&client->dev, "%s Programmable led chip found\n", id->name);
347 347
348 ret = lp55xx_register_leds(led, chip); 348 ret = lp55xx_register_leds(led, chip);
349 if (ret) 349 if (ret)
350 goto err_register_leds; 350 goto err_register_leds;
351 351
352 ret = lp55xx_register_sysfs(chip); 352 ret = lp55xx_register_sysfs(chip);
353 if (ret) { 353 if (ret) {
354 dev_err(&client->dev, "registering sysfs failed\n"); 354 dev_err(&client->dev, "registering sysfs failed\n");
355 goto err_register_sysfs; 355 goto err_register_sysfs;
356 } 356 }
357 357
358 return 0; 358 return 0;
359 359
360 err_register_sysfs: 360 err_register_sysfs:
361 lp55xx_unregister_leds(led, chip); 361 lp55xx_unregister_leds(led, chip);
362 err_register_leds: 362 err_register_leds:
363 lp55xx_deinit_device(chip); 363 lp55xx_deinit_device(chip);
364 err_init: 364 err_init:
365 return ret; 365 return ret;
366 } 366 }
367 367
368 static int lp8501_remove(struct i2c_client *client) 368 static int lp8501_remove(struct i2c_client *client)
369 { 369 {
370 struct lp55xx_led *led = i2c_get_clientdata(client); 370 struct lp55xx_led *led = i2c_get_clientdata(client);
371 struct lp55xx_chip *chip = led->chip; 371 struct lp55xx_chip *chip = led->chip;
372 372
373 lp8501_stop_engine(chip); 373 lp8501_stop_engine(chip);
374 lp55xx_unregister_sysfs(chip); 374 lp55xx_unregister_sysfs(chip);
375 lp55xx_unregister_leds(led, chip); 375 lp55xx_unregister_leds(led, chip);
376 lp55xx_deinit_device(chip); 376 lp55xx_deinit_device(chip);
377 377
378 return 0; 378 return 0;
379 } 379 }
380 380
381 static const struct i2c_device_id lp8501_id[] = { 381 static const struct i2c_device_id lp8501_id[] = {
382 { "lp8501", 0 }, 382 { "lp8501", 0 },
383 { } 383 { }
384 }; 384 };
385 MODULE_DEVICE_TABLE(i2c, lp8501_id); 385 MODULE_DEVICE_TABLE(i2c, lp8501_id);
386 386
387 #ifdef CONFIG_OF 387 #ifdef CONFIG_OF
388 static const struct of_device_id of_lp8501_leds_match[] = { 388 static const struct of_device_id of_lp8501_leds_match[] = {
389 { .compatible = "ti,lp8501", }, 389 { .compatible = "ti,lp8501", },
390 {}, 390 {},
391 }; 391 };
392 392
393 MODULE_DEVICE_TABLE(of, of_lp8501_leds_match); 393 MODULE_DEVICE_TABLE(of, of_lp8501_leds_match);
394 #endif 394 #endif
395 395
396 static struct i2c_driver lp8501_driver = { 396 static struct i2c_driver lp8501_driver = {
397 .driver = { 397 .driver = {
398 .name = "lp8501", 398 .name = "lp8501",
399 .of_match_table = of_match_ptr(of_lp8501_leds_match), 399 .of_match_table = of_match_ptr(of_lp8501_leds_match),
400 }, 400 },
401 .probe = lp8501_probe, 401 .probe = lp8501_probe,
402 .remove = lp8501_remove, 402 .remove = lp8501_remove,
403 .id_table = lp8501_id, 403 .id_table = lp8501_id,
404 }; 404 };
405 405
406 module_i2c_driver(lp8501_driver); 406 module_i2c_driver(lp8501_driver);
407 407
408 MODULE_DESCRIPTION("Texas Instruments LP8501 LED drvier"); 408 MODULE_DESCRIPTION("Texas Instruments LP8501 LED drvier");
409 MODULE_AUTHOR("Milo Kim"); 409 MODULE_AUTHOR("Milo Kim");
410 MODULE_LICENSE("GPL"); 410 MODULE_LICENSE("GPL");
411 411
drivers/leds/leds-lt3593.c
1 /* 1 /*
2 * LEDs driver for LT3593 controllers 2 * LEDs driver for LT3593 controllers
3 * 3 *
4 * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf 4 * See the datasheet at http://cds.linear.com/docs/Datasheet/3593f.pdf
5 * 5 *
6 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> 6 * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
7 * 7 *
8 * Based on leds-gpio.c, 8 * Based on leds-gpio.c,
9 * 9 *
10 * Copyright (C) 2007 8D Technologies inc. 10 * Copyright (C) 2007 8D Technologies inc.
11 * Raphael Assenat <raph@8d.com> 11 * Raphael Assenat <raph@8d.com>
12 * Copyright (C) 2008 Freescale Semiconductor, Inc. 12 * Copyright (C) 2008 Freescale Semiconductor, Inc.
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as 15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation. 16 * published by the Free Software Foundation.
17 */ 17 */
18 18
19 #include <linux/kernel.h> 19 #include <linux/kernel.h>
20 #include <linux/init.h> 20 #include <linux/init.h>
21 #include <linux/platform_device.h> 21 #include <linux/platform_device.h>
22 #include <linux/leds.h> 22 #include <linux/leds.h>
23 #include <linux/workqueue.h> 23 #include <linux/workqueue.h>
24 #include <linux/delay.h> 24 #include <linux/delay.h>
25 #include <linux/gpio.h> 25 #include <linux/gpio.h>
26 #include <linux/slab.h> 26 #include <linux/slab.h>
27 #include <linux/module.h> 27 #include <linux/module.h>
28 28
29 struct lt3593_led_data { 29 struct lt3593_led_data {
30 struct led_classdev cdev; 30 struct led_classdev cdev;
31 unsigned gpio; 31 unsigned gpio;
32 struct work_struct work; 32 struct work_struct work;
33 u8 new_level; 33 u8 new_level;
34 }; 34 };
35 35
36 static void lt3593_led_work(struct work_struct *work) 36 static void lt3593_led_work(struct work_struct *work)
37 { 37 {
38 int pulses; 38 int pulses;
39 struct lt3593_led_data *led_dat = 39 struct lt3593_led_data *led_dat =
40 container_of(work, struct lt3593_led_data, work); 40 container_of(work, struct lt3593_led_data, work);
41 41
42 /* 42 /*
43 * The LT3593 resets its internal current level register to the maximum 43 * The LT3593 resets its internal current level register to the maximum
44 * level on the first falling edge on the control pin. Each following 44 * level on the first falling edge on the control pin. Each following
45 * falling edge decreases the current level by 625uA. Up to 32 pulses 45 * falling edge decreases the current level by 625uA. Up to 32 pulses
46 * can be sent, so the maximum power reduction is 20mA. 46 * can be sent, so the maximum power reduction is 20mA.
47 * After a timeout of 128us, the value is taken from the register and 47 * After a timeout of 128us, the value is taken from the register and
48 * applied is to the output driver. 48 * applied is to the output driver.
49 */ 49 */
50 50
51 if (led_dat->new_level == 0) { 51 if (led_dat->new_level == 0) {
52 gpio_set_value_cansleep(led_dat->gpio, 0); 52 gpio_set_value_cansleep(led_dat->gpio, 0);
53 return; 53 return;
54 } 54 }
55 55
56 pulses = 32 - (led_dat->new_level * 32) / 255; 56 pulses = 32 - (led_dat->new_level * 32) / 255;
57 57
58 if (pulses == 0) { 58 if (pulses == 0) {
59 gpio_set_value_cansleep(led_dat->gpio, 0); 59 gpio_set_value_cansleep(led_dat->gpio, 0);
60 mdelay(1); 60 mdelay(1);
61 gpio_set_value_cansleep(led_dat->gpio, 1); 61 gpio_set_value_cansleep(led_dat->gpio, 1);
62 return; 62 return;
63 } 63 }
64 64
65 gpio_set_value_cansleep(led_dat->gpio, 1); 65 gpio_set_value_cansleep(led_dat->gpio, 1);
66 66
67 while (pulses--) { 67 while (pulses--) {
68 gpio_set_value_cansleep(led_dat->gpio, 0); 68 gpio_set_value_cansleep(led_dat->gpio, 0);
69 udelay(1); 69 udelay(1);
70 gpio_set_value_cansleep(led_dat->gpio, 1); 70 gpio_set_value_cansleep(led_dat->gpio, 1);
71 udelay(1); 71 udelay(1);
72 } 72 }
73 } 73 }
74 74
75 static void lt3593_led_set(struct led_classdev *led_cdev, 75 static void lt3593_led_set(struct led_classdev *led_cdev,
76 enum led_brightness value) 76 enum led_brightness value)
77 { 77 {
78 struct lt3593_led_data *led_dat = 78 struct lt3593_led_data *led_dat =
79 container_of(led_cdev, struct lt3593_led_data, cdev); 79 container_of(led_cdev, struct lt3593_led_data, cdev);
80 80
81 led_dat->new_level = value; 81 led_dat->new_level = value;
82 schedule_work(&led_dat->work); 82 schedule_work(&led_dat->work);
83 } 83 }
84 84
85 static int create_lt3593_led(const struct gpio_led *template, 85 static int create_lt3593_led(const struct gpio_led *template,
86 struct lt3593_led_data *led_dat, struct device *parent) 86 struct lt3593_led_data *led_dat, struct device *parent)
87 { 87 {
88 int ret, state; 88 int ret, state;
89 89
90 /* skip leds on GPIOs that aren't available */ 90 /* skip leds on GPIOs that aren't available */
91 if (!gpio_is_valid(template->gpio)) { 91 if (!gpio_is_valid(template->gpio)) {
92 dev_info(parent, "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n", 92 dev_info(parent, "%s: skipping unavailable LT3593 LED at gpio %d (%s)\n",
93 KBUILD_MODNAME, template->gpio, template->name); 93 KBUILD_MODNAME, template->gpio, template->name);
94 return 0; 94 return 0;
95 } 95 }
96 96
97 led_dat->cdev.name = template->name; 97 led_dat->cdev.name = template->name;
98 led_dat->cdev.default_trigger = template->default_trigger; 98 led_dat->cdev.default_trigger = template->default_trigger;
99 led_dat->gpio = template->gpio; 99 led_dat->gpio = template->gpio;
100 100
101 led_dat->cdev.brightness_set = lt3593_led_set; 101 led_dat->cdev.brightness_set = lt3593_led_set;
102 102
103 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON); 103 state = (template->default_state == LEDS_GPIO_DEFSTATE_ON);
104 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF; 104 led_dat->cdev.brightness = state ? LED_FULL : LED_OFF;
105 105
106 if (!template->retain_state_suspended) 106 if (!template->retain_state_suspended)
107 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 107 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
108 108
109 ret = devm_gpio_request_one(parent, template->gpio, state ? 109 ret = devm_gpio_request_one(parent, template->gpio, state ?
110 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, 110 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
111 template->name); 111 template->name);
112 if (ret < 0) 112 if (ret < 0)
113 return ret; 113 return ret;
114 114
115 INIT_WORK(&led_dat->work, lt3593_led_work); 115 INIT_WORK(&led_dat->work, lt3593_led_work);
116 116
117 ret = led_classdev_register(parent, &led_dat->cdev); 117 ret = led_classdev_register(parent, &led_dat->cdev);
118 if (ret < 0) 118 if (ret < 0)
119 return ret; 119 return ret;
120 120
121 dev_info(parent, "%s: registered LT3593 LED '%s' at GPIO %d\n", 121 dev_info(parent, "%s: registered LT3593 LED '%s' at GPIO %d\n",
122 KBUILD_MODNAME, template->name, template->gpio); 122 KBUILD_MODNAME, template->name, template->gpio);
123 123
124 return 0; 124 return 0;
125 } 125 }
126 126
127 static void delete_lt3593_led(struct lt3593_led_data *led) 127 static void delete_lt3593_led(struct lt3593_led_data *led)
128 { 128 {
129 if (!gpio_is_valid(led->gpio)) 129 if (!gpio_is_valid(led->gpio))
130 return; 130 return;
131 131
132 led_classdev_unregister(&led->cdev); 132 led_classdev_unregister(&led->cdev);
133 cancel_work_sync(&led->work); 133 cancel_work_sync(&led->work);
134 } 134 }
135 135
136 static int lt3593_led_probe(struct platform_device *pdev) 136 static int lt3593_led_probe(struct platform_device *pdev)
137 { 137 {
138 struct gpio_led_platform_data *pdata = pdev->dev.platform_data; 138 struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
139 struct lt3593_led_data *leds_data; 139 struct lt3593_led_data *leds_data;
140 int i, ret = 0; 140 int i, ret = 0;
141 141
142 if (!pdata) 142 if (!pdata)
143 return -EBUSY; 143 return -EBUSY;
144 144
145 leds_data = devm_kzalloc(&pdev->dev, 145 leds_data = devm_kzalloc(&pdev->dev,
146 sizeof(struct lt3593_led_data) * pdata->num_leds, 146 sizeof(struct lt3593_led_data) * pdata->num_leds,
147 GFP_KERNEL); 147 GFP_KERNEL);
148 if (!leds_data) 148 if (!leds_data)
149 return -ENOMEM; 149 return -ENOMEM;
150 150
151 for (i = 0; i < pdata->num_leds; i++) { 151 for (i = 0; i < pdata->num_leds; i++) {
152 ret = create_lt3593_led(&pdata->leds[i], &leds_data[i], 152 ret = create_lt3593_led(&pdata->leds[i], &leds_data[i],
153 &pdev->dev); 153 &pdev->dev);
154 if (ret < 0) 154 if (ret < 0)
155 goto err; 155 goto err;
156 } 156 }
157 157
158 platform_set_drvdata(pdev, leds_data); 158 platform_set_drvdata(pdev, leds_data);
159 159
160 return 0; 160 return 0;
161 161
162 err: 162 err:
163 for (i = i - 1; i >= 0; i--) 163 for (i = i - 1; i >= 0; i--)
164 delete_lt3593_led(&leds_data[i]); 164 delete_lt3593_led(&leds_data[i]);
165 165
166 return ret; 166 return ret;
167 } 167 }
168 168
169 static int lt3593_led_remove(struct platform_device *pdev) 169 static int lt3593_led_remove(struct platform_device *pdev)
170 { 170 {
171 int i; 171 int i;
172 struct gpio_led_platform_data *pdata = pdev->dev.platform_data; 172 struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
173 struct lt3593_led_data *leds_data; 173 struct lt3593_led_data *leds_data;
174 174
175 leds_data = platform_get_drvdata(pdev); 175 leds_data = platform_get_drvdata(pdev);
176 176
177 for (i = 0; i < pdata->num_leds; i++) 177 for (i = 0; i < pdata->num_leds; i++)
178 delete_lt3593_led(&leds_data[i]); 178 delete_lt3593_led(&leds_data[i]);
179 179
180 return 0; 180 return 0;
181 } 181 }
182 182
183 static struct platform_driver lt3593_led_driver = { 183 static struct platform_driver lt3593_led_driver = {
184 .probe = lt3593_led_probe, 184 .probe = lt3593_led_probe,
185 .remove = lt3593_led_remove, 185 .remove = lt3593_led_remove,
186 .driver = { 186 .driver = {
187 .name = "leds-lt3593", 187 .name = "leds-lt3593",
188 .owner = THIS_MODULE, 188 .owner = THIS_MODULE,
189 }, 189 },
190 }; 190 };
191 191
192 module_platform_driver(lt3593_led_driver); 192 module_platform_driver(lt3593_led_driver);
193 193
194 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); 194 MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
195 MODULE_DESCRIPTION("LED driver for LT3593 controllers"); 195 MODULE_DESCRIPTION("LED driver for LT3593 controllers");
196 MODULE_LICENSE("GPL"); 196 MODULE_LICENSE("GPL");
197 MODULE_ALIAS("platform:leds-lt3593"); 197 MODULE_ALIAS("platform:leds-lt3593");
198 198
drivers/leds/leds-netxbig.c
1 /* 1 /*
2 * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs 2 * leds-netxbig.c - Driver for the 2Big and 5Big Network series LEDs
3 * 3 *
4 * Copyright (C) 2010 LaCie 4 * Copyright (C) 2010 LaCie
5 * 5 *
6 * Author: Simon Guinot <sguinot@lacie.com> 6 * Author: Simon Guinot <sguinot@lacie.com>
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version. 11 * (at your option) any later version.
12 * 12 *
13 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details. 16 * GNU General Public License for more details.
17 * 17 *
18 * You should have received a copy of the GNU General Public License 18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */ 21 */
22 22
23 #include <linux/module.h> 23 #include <linux/module.h>
24 #include <linux/init.h> 24 #include <linux/init.h>
25 #include <linux/irq.h> 25 #include <linux/irq.h>
26 #include <linux/slab.h> 26 #include <linux/slab.h>
27 #include <linux/spinlock.h> 27 #include <linux/spinlock.h>
28 #include <linux/platform_device.h> 28 #include <linux/platform_device.h>
29 #include <linux/gpio.h> 29 #include <linux/gpio.h>
30 #include <linux/leds.h> 30 #include <linux/leds.h>
31 #include <linux/platform_data/leds-kirkwood-netxbig.h> 31 #include <linux/platform_data/leds-kirkwood-netxbig.h>
32 32
33 /* 33 /*
34 * GPIO extension bus. 34 * GPIO extension bus.
35 */ 35 */
36 36
37 static DEFINE_SPINLOCK(gpio_ext_lock); 37 static DEFINE_SPINLOCK(gpio_ext_lock);
38 38
39 static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr) 39 static void gpio_ext_set_addr(struct netxbig_gpio_ext *gpio_ext, int addr)
40 { 40 {
41 int pin; 41 int pin;
42 42
43 for (pin = 0; pin < gpio_ext->num_addr; pin++) 43 for (pin = 0; pin < gpio_ext->num_addr; pin++)
44 gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1); 44 gpio_set_value(gpio_ext->addr[pin], (addr >> pin) & 1);
45 } 45 }
46 46
47 static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data) 47 static void gpio_ext_set_data(struct netxbig_gpio_ext *gpio_ext, int data)
48 { 48 {
49 int pin; 49 int pin;
50 50
51 for (pin = 0; pin < gpio_ext->num_data; pin++) 51 for (pin = 0; pin < gpio_ext->num_data; pin++)
52 gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1); 52 gpio_set_value(gpio_ext->data[pin], (data >> pin) & 1);
53 } 53 }
54 54
55 static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext) 55 static void gpio_ext_enable_select(struct netxbig_gpio_ext *gpio_ext)
56 { 56 {
57 /* Enable select is done on the raising edge. */ 57 /* Enable select is done on the raising edge. */
58 gpio_set_value(gpio_ext->enable, 0); 58 gpio_set_value(gpio_ext->enable, 0);
59 gpio_set_value(gpio_ext->enable, 1); 59 gpio_set_value(gpio_ext->enable, 1);
60 } 60 }
61 61
62 static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext, 62 static void gpio_ext_set_value(struct netxbig_gpio_ext *gpio_ext,
63 int addr, int value) 63 int addr, int value)
64 { 64 {
65 unsigned long flags; 65 unsigned long flags;
66 66
67 spin_lock_irqsave(&gpio_ext_lock, flags); 67 spin_lock_irqsave(&gpio_ext_lock, flags);
68 gpio_ext_set_addr(gpio_ext, addr); 68 gpio_ext_set_addr(gpio_ext, addr);
69 gpio_ext_set_data(gpio_ext, value); 69 gpio_ext_set_data(gpio_ext, value);
70 gpio_ext_enable_select(gpio_ext); 70 gpio_ext_enable_select(gpio_ext);
71 spin_unlock_irqrestore(&gpio_ext_lock, flags); 71 spin_unlock_irqrestore(&gpio_ext_lock, flags);
72 } 72 }
73 73
74 static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext) 74 static int gpio_ext_init(struct netxbig_gpio_ext *gpio_ext)
75 { 75 {
76 int err; 76 int err;
77 int i; 77 int i;
78 78
79 if (unlikely(!gpio_ext)) 79 if (unlikely(!gpio_ext))
80 return -EINVAL; 80 return -EINVAL;
81 81
82 /* Configure address GPIOs. */ 82 /* Configure address GPIOs. */
83 for (i = 0; i < gpio_ext->num_addr; i++) { 83 for (i = 0; i < gpio_ext->num_addr; i++) {
84 err = gpio_request_one(gpio_ext->addr[i], GPIOF_OUT_INIT_LOW, 84 err = gpio_request_one(gpio_ext->addr[i], GPIOF_OUT_INIT_LOW,
85 "GPIO extension addr"); 85 "GPIO extension addr");
86 if (err) 86 if (err)
87 goto err_free_addr; 87 goto err_free_addr;
88 } 88 }
89 /* Configure data GPIOs. */ 89 /* Configure data GPIOs. */
90 for (i = 0; i < gpio_ext->num_data; i++) { 90 for (i = 0; i < gpio_ext->num_data; i++) {
91 err = gpio_request_one(gpio_ext->data[i], GPIOF_OUT_INIT_LOW, 91 err = gpio_request_one(gpio_ext->data[i], GPIOF_OUT_INIT_LOW,
92 "GPIO extension data"); 92 "GPIO extension data");
93 if (err) 93 if (err)
94 goto err_free_data; 94 goto err_free_data;
95 } 95 }
96 /* Configure "enable select" GPIO. */ 96 /* Configure "enable select" GPIO. */
97 err = gpio_request_one(gpio_ext->enable, GPIOF_OUT_INIT_LOW, 97 err = gpio_request_one(gpio_ext->enable, GPIOF_OUT_INIT_LOW,
98 "GPIO extension enable"); 98 "GPIO extension enable");
99 if (err) 99 if (err)
100 goto err_free_data; 100 goto err_free_data;
101 101
102 return 0; 102 return 0;
103 103
104 err_free_data: 104 err_free_data:
105 for (i = i - 1; i >= 0; i--) 105 for (i = i - 1; i >= 0; i--)
106 gpio_free(gpio_ext->data[i]); 106 gpio_free(gpio_ext->data[i]);
107 i = gpio_ext->num_addr; 107 i = gpio_ext->num_addr;
108 err_free_addr: 108 err_free_addr:
109 for (i = i - 1; i >= 0; i--) 109 for (i = i - 1; i >= 0; i--)
110 gpio_free(gpio_ext->addr[i]); 110 gpio_free(gpio_ext->addr[i]);
111 111
112 return err; 112 return err;
113 } 113 }
114 114
115 static void gpio_ext_free(struct netxbig_gpio_ext *gpio_ext) 115 static void gpio_ext_free(struct netxbig_gpio_ext *gpio_ext)
116 { 116 {
117 int i; 117 int i;
118 118
119 gpio_free(gpio_ext->enable); 119 gpio_free(gpio_ext->enable);
120 for (i = gpio_ext->num_addr - 1; i >= 0; i--) 120 for (i = gpio_ext->num_addr - 1; i >= 0; i--)
121 gpio_free(gpio_ext->addr[i]); 121 gpio_free(gpio_ext->addr[i]);
122 for (i = gpio_ext->num_data - 1; i >= 0; i--) 122 for (i = gpio_ext->num_data - 1; i >= 0; i--)
123 gpio_free(gpio_ext->data[i]); 123 gpio_free(gpio_ext->data[i]);
124 } 124 }
125 125
126 /* 126 /*
127 * Class LED driver. 127 * Class LED driver.
128 */ 128 */
129 129
130 struct netxbig_led_data { 130 struct netxbig_led_data {
131 struct netxbig_gpio_ext *gpio_ext; 131 struct netxbig_gpio_ext *gpio_ext;
132 struct led_classdev cdev; 132 struct led_classdev cdev;
133 int mode_addr; 133 int mode_addr;
134 int *mode_val; 134 int *mode_val;
135 int bright_addr; 135 int bright_addr;
136 int bright_max; 136 int bright_max;
137 struct netxbig_led_timer *timer; 137 struct netxbig_led_timer *timer;
138 int num_timer; 138 int num_timer;
139 enum netxbig_led_mode mode; 139 enum netxbig_led_mode mode;
140 int sata; 140 int sata;
141 spinlock_t lock; 141 spinlock_t lock;
142 }; 142 };
143 143
144 static int netxbig_led_get_timer_mode(enum netxbig_led_mode *mode, 144 static int netxbig_led_get_timer_mode(enum netxbig_led_mode *mode,
145 unsigned long delay_on, 145 unsigned long delay_on,
146 unsigned long delay_off, 146 unsigned long delay_off,
147 struct netxbig_led_timer *timer, 147 struct netxbig_led_timer *timer,
148 int num_timer) 148 int num_timer)
149 { 149 {
150 int i; 150 int i;
151 151
152 for (i = 0; i < num_timer; i++) { 152 for (i = 0; i < num_timer; i++) {
153 if (timer[i].delay_on == delay_on && 153 if (timer[i].delay_on == delay_on &&
154 timer[i].delay_off == delay_off) { 154 timer[i].delay_off == delay_off) {
155 *mode = timer[i].mode; 155 *mode = timer[i].mode;
156 return 0; 156 return 0;
157 } 157 }
158 } 158 }
159 return -EINVAL; 159 return -EINVAL;
160 } 160 }
161 161
162 static int netxbig_led_blink_set(struct led_classdev *led_cdev, 162 static int netxbig_led_blink_set(struct led_classdev *led_cdev,
163 unsigned long *delay_on, 163 unsigned long *delay_on,
164 unsigned long *delay_off) 164 unsigned long *delay_off)
165 { 165 {
166 struct netxbig_led_data *led_dat = 166 struct netxbig_led_data *led_dat =
167 container_of(led_cdev, struct netxbig_led_data, cdev); 167 container_of(led_cdev, struct netxbig_led_data, cdev);
168 enum netxbig_led_mode mode; 168 enum netxbig_led_mode mode;
169 int mode_val; 169 int mode_val;
170 int ret; 170 int ret;
171 171
172 /* Look for a LED mode with the requested timer frequency. */ 172 /* Look for a LED mode with the requested timer frequency. */
173 ret = netxbig_led_get_timer_mode(&mode, *delay_on, *delay_off, 173 ret = netxbig_led_get_timer_mode(&mode, *delay_on, *delay_off,
174 led_dat->timer, led_dat->num_timer); 174 led_dat->timer, led_dat->num_timer);
175 if (ret < 0) 175 if (ret < 0)
176 return ret; 176 return ret;
177 177
178 mode_val = led_dat->mode_val[mode]; 178 mode_val = led_dat->mode_val[mode];
179 if (mode_val == NETXBIG_LED_INVALID_MODE) 179 if (mode_val == NETXBIG_LED_INVALID_MODE)
180 return -EINVAL; 180 return -EINVAL;
181 181
182 spin_lock_irq(&led_dat->lock); 182 spin_lock_irq(&led_dat->lock);
183 183
184 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); 184 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
185 led_dat->mode = mode; 185 led_dat->mode = mode;
186 186
187 spin_unlock_irq(&led_dat->lock); 187 spin_unlock_irq(&led_dat->lock);
188 188
189 return 0; 189 return 0;
190 } 190 }
191 191
192 static void netxbig_led_set(struct led_classdev *led_cdev, 192 static void netxbig_led_set(struct led_classdev *led_cdev,
193 enum led_brightness value) 193 enum led_brightness value)
194 { 194 {
195 struct netxbig_led_data *led_dat = 195 struct netxbig_led_data *led_dat =
196 container_of(led_cdev, struct netxbig_led_data, cdev); 196 container_of(led_cdev, struct netxbig_led_data, cdev);
197 enum netxbig_led_mode mode; 197 enum netxbig_led_mode mode;
198 int mode_val, bright_val; 198 int mode_val, bright_val;
199 int set_brightness = 1; 199 int set_brightness = 1;
200 unsigned long flags; 200 unsigned long flags;
201 201
202 spin_lock_irqsave(&led_dat->lock, flags); 202 spin_lock_irqsave(&led_dat->lock, flags);
203 203
204 if (value == LED_OFF) { 204 if (value == LED_OFF) {
205 mode = NETXBIG_LED_OFF; 205 mode = NETXBIG_LED_OFF;
206 set_brightness = 0; 206 set_brightness = 0;
207 } else { 207 } else {
208 if (led_dat->sata) 208 if (led_dat->sata)
209 mode = NETXBIG_LED_SATA; 209 mode = NETXBIG_LED_SATA;
210 else if (led_dat->mode == NETXBIG_LED_OFF) 210 else if (led_dat->mode == NETXBIG_LED_OFF)
211 mode = NETXBIG_LED_ON; 211 mode = NETXBIG_LED_ON;
212 else /* Keep 'timer' mode. */ 212 else /* Keep 'timer' mode. */
213 mode = led_dat->mode; 213 mode = led_dat->mode;
214 } 214 }
215 mode_val = led_dat->mode_val[mode]; 215 mode_val = led_dat->mode_val[mode];
216 216
217 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); 217 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
218 led_dat->mode = mode; 218 led_dat->mode = mode;
219 /* 219 /*
220 * Note that the brightness register is shared between all the 220 * Note that the brightness register is shared between all the
221 * SATA LEDs. So, change the brightness setting for a single 221 * SATA LEDs. So, change the brightness setting for a single
222 * SATA LED will affect all the others. 222 * SATA LED will affect all the others.
223 */ 223 */
224 if (set_brightness) { 224 if (set_brightness) {
225 bright_val = DIV_ROUND_UP(value * led_dat->bright_max, 225 bright_val = DIV_ROUND_UP(value * led_dat->bright_max,
226 LED_FULL); 226 LED_FULL);
227 gpio_ext_set_value(led_dat->gpio_ext, 227 gpio_ext_set_value(led_dat->gpio_ext,
228 led_dat->bright_addr, bright_val); 228 led_dat->bright_addr, bright_val);
229 } 229 }
230 230
231 spin_unlock_irqrestore(&led_dat->lock, flags); 231 spin_unlock_irqrestore(&led_dat->lock, flags);
232 } 232 }
233 233
234 static ssize_t netxbig_led_sata_store(struct device *dev, 234 static ssize_t netxbig_led_sata_store(struct device *dev,
235 struct device_attribute *attr, 235 struct device_attribute *attr,
236 const char *buff, size_t count) 236 const char *buff, size_t count)
237 { 237 {
238 struct led_classdev *led_cdev = dev_get_drvdata(dev); 238 struct led_classdev *led_cdev = dev_get_drvdata(dev);
239 struct netxbig_led_data *led_dat = 239 struct netxbig_led_data *led_dat =
240 container_of(led_cdev, struct netxbig_led_data, cdev); 240 container_of(led_cdev, struct netxbig_led_data, cdev);
241 unsigned long enable; 241 unsigned long enable;
242 enum netxbig_led_mode mode; 242 enum netxbig_led_mode mode;
243 int mode_val; 243 int mode_val;
244 int ret; 244 int ret;
245 245
246 ret = kstrtoul(buff, 10, &enable); 246 ret = kstrtoul(buff, 10, &enable);
247 if (ret < 0) 247 if (ret < 0)
248 return ret; 248 return ret;
249 249
250 enable = !!enable; 250 enable = !!enable;
251 251
252 spin_lock_irq(&led_dat->lock); 252 spin_lock_irq(&led_dat->lock);
253 253
254 if (led_dat->sata == enable) { 254 if (led_dat->sata == enable) {
255 ret = count; 255 ret = count;
256 goto exit_unlock; 256 goto exit_unlock;
257 } 257 }
258 258
259 if (led_dat->mode != NETXBIG_LED_ON && 259 if (led_dat->mode != NETXBIG_LED_ON &&
260 led_dat->mode != NETXBIG_LED_SATA) 260 led_dat->mode != NETXBIG_LED_SATA)
261 mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */ 261 mode = led_dat->mode; /* Keep modes 'off' and 'timer'. */
262 else if (enable) 262 else if (enable)
263 mode = NETXBIG_LED_SATA; 263 mode = NETXBIG_LED_SATA;
264 else 264 else
265 mode = NETXBIG_LED_ON; 265 mode = NETXBIG_LED_ON;
266 266
267 mode_val = led_dat->mode_val[mode]; 267 mode_val = led_dat->mode_val[mode];
268 if (mode_val == NETXBIG_LED_INVALID_MODE) { 268 if (mode_val == NETXBIG_LED_INVALID_MODE) {
269 ret = -EINVAL; 269 ret = -EINVAL;
270 goto exit_unlock; 270 goto exit_unlock;
271 } 271 }
272 272
273 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val); 273 gpio_ext_set_value(led_dat->gpio_ext, led_dat->mode_addr, mode_val);
274 led_dat->mode = mode; 274 led_dat->mode = mode;
275 led_dat->sata = enable; 275 led_dat->sata = enable;
276 276
277 ret = count; 277 ret = count;
278 278
279 exit_unlock: 279 exit_unlock:
280 spin_unlock_irq(&led_dat->lock); 280 spin_unlock_irq(&led_dat->lock);
281 281
282 return ret; 282 return ret;
283 } 283 }
284 284
285 static ssize_t netxbig_led_sata_show(struct device *dev, 285 static ssize_t netxbig_led_sata_show(struct device *dev,
286 struct device_attribute *attr, char *buf) 286 struct device_attribute *attr, char *buf)
287 { 287 {
288 struct led_classdev *led_cdev = dev_get_drvdata(dev); 288 struct led_classdev *led_cdev = dev_get_drvdata(dev);
289 struct netxbig_led_data *led_dat = 289 struct netxbig_led_data *led_dat =
290 container_of(led_cdev, struct netxbig_led_data, cdev); 290 container_of(led_cdev, struct netxbig_led_data, cdev);
291 291
292 return sprintf(buf, "%d\n", led_dat->sata); 292 return sprintf(buf, "%d\n", led_dat->sata);
293 } 293 }
294 294
295 static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store); 295 static DEVICE_ATTR(sata, 0644, netxbig_led_sata_show, netxbig_led_sata_store);
296 296
297 static void delete_netxbig_led(struct netxbig_led_data *led_dat) 297 static void delete_netxbig_led(struct netxbig_led_data *led_dat)
298 { 298 {
299 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) 299 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE)
300 device_remove_file(led_dat->cdev.dev, &dev_attr_sata); 300 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
301 led_classdev_unregister(&led_dat->cdev); 301 led_classdev_unregister(&led_dat->cdev);
302 } 302 }
303 303
304 static int 304 static int
305 create_netxbig_led(struct platform_device *pdev, 305 create_netxbig_led(struct platform_device *pdev,
306 struct netxbig_led_data *led_dat, 306 struct netxbig_led_data *led_dat,
307 const struct netxbig_led *template) 307 const struct netxbig_led *template)
308 { 308 {
309 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; 309 struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
310 int ret; 310 int ret;
311 311
312 spin_lock_init(&led_dat->lock); 312 spin_lock_init(&led_dat->lock);
313 led_dat->gpio_ext = pdata->gpio_ext; 313 led_dat->gpio_ext = pdata->gpio_ext;
314 led_dat->cdev.name = template->name; 314 led_dat->cdev.name = template->name;
315 led_dat->cdev.default_trigger = template->default_trigger; 315 led_dat->cdev.default_trigger = template->default_trigger;
316 led_dat->cdev.blink_set = netxbig_led_blink_set; 316 led_dat->cdev.blink_set = netxbig_led_blink_set;
317 led_dat->cdev.brightness_set = netxbig_led_set; 317 led_dat->cdev.brightness_set = netxbig_led_set;
318 /* 318 /*
319 * Because the GPIO extension bus don't allow to read registers 319 * Because the GPIO extension bus don't allow to read registers
320 * value, there is no way to probe the LED initial state. 320 * value, there is no way to probe the LED initial state.
321 * So, the initial sysfs LED value for the "brightness" and "sata" 321 * So, the initial sysfs LED value for the "brightness" and "sata"
322 * attributes are inconsistent. 322 * attributes are inconsistent.
323 * 323 *
324 * Note that the initial LED state can't be reconfigured. 324 * Note that the initial LED state can't be reconfigured.
325 * The reason is that the LED behaviour must stay uniform during 325 * The reason is that the LED behaviour must stay uniform during
326 * the whole boot process (bootloader+linux). 326 * the whole boot process (bootloader+linux).
327 */ 327 */
328 led_dat->sata = 0; 328 led_dat->sata = 0;
329 led_dat->cdev.brightness = LED_OFF; 329 led_dat->cdev.brightness = LED_OFF;
330 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 330 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
331 led_dat->mode_addr = template->mode_addr; 331 led_dat->mode_addr = template->mode_addr;
332 led_dat->mode_val = template->mode_val; 332 led_dat->mode_val = template->mode_val;
333 led_dat->bright_addr = template->bright_addr; 333 led_dat->bright_addr = template->bright_addr;
334 led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1; 334 led_dat->bright_max = (1 << pdata->gpio_ext->num_data) - 1;
335 led_dat->timer = pdata->timer; 335 led_dat->timer = pdata->timer;
336 led_dat->num_timer = pdata->num_timer; 336 led_dat->num_timer = pdata->num_timer;
337 337
338 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 338 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
339 if (ret < 0) 339 if (ret < 0)
340 return ret; 340 return ret;
341 341
342 /* 342 /*
343 * If available, expose the SATA activity blink capability through 343 * If available, expose the SATA activity blink capability through
344 * a "sata" sysfs attribute. 344 * a "sata" sysfs attribute.
345 */ 345 */
346 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) { 346 if (led_dat->mode_val[NETXBIG_LED_SATA] != NETXBIG_LED_INVALID_MODE) {
347 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata); 347 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
348 if (ret) 348 if (ret)
349 led_classdev_unregister(&led_dat->cdev); 349 led_classdev_unregister(&led_dat->cdev);
350 } 350 }
351 351
352 return ret; 352 return ret;
353 } 353 }
354 354
355 static int netxbig_led_probe(struct platform_device *pdev) 355 static int netxbig_led_probe(struct platform_device *pdev)
356 { 356 {
357 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; 357 struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
358 struct netxbig_led_data *leds_data; 358 struct netxbig_led_data *leds_data;
359 int i; 359 int i;
360 int ret; 360 int ret;
361 361
362 if (!pdata) 362 if (!pdata)
363 return -EINVAL; 363 return -EINVAL;
364 364
365 leds_data = devm_kzalloc(&pdev->dev, 365 leds_data = devm_kzalloc(&pdev->dev,
366 sizeof(struct netxbig_led_data) * pdata->num_leds, GFP_KERNEL); 366 sizeof(struct netxbig_led_data) * pdata->num_leds, GFP_KERNEL);
367 if (!leds_data) 367 if (!leds_data)
368 return -ENOMEM; 368 return -ENOMEM;
369 369
370 ret = gpio_ext_init(pdata->gpio_ext); 370 ret = gpio_ext_init(pdata->gpio_ext);
371 if (ret < 0) 371 if (ret < 0)
372 return ret; 372 return ret;
373 373
374 for (i = 0; i < pdata->num_leds; i++) { 374 for (i = 0; i < pdata->num_leds; i++) {
375 ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]); 375 ret = create_netxbig_led(pdev, &leds_data[i], &pdata->leds[i]);
376 if (ret < 0) 376 if (ret < 0)
377 goto err_free_leds; 377 goto err_free_leds;
378 } 378 }
379 379
380 platform_set_drvdata(pdev, leds_data); 380 platform_set_drvdata(pdev, leds_data);
381 381
382 return 0; 382 return 0;
383 383
384 err_free_leds: 384 err_free_leds:
385 for (i = i - 1; i >= 0; i--) 385 for (i = i - 1; i >= 0; i--)
386 delete_netxbig_led(&leds_data[i]); 386 delete_netxbig_led(&leds_data[i]);
387 387
388 gpio_ext_free(pdata->gpio_ext); 388 gpio_ext_free(pdata->gpio_ext);
389 return ret; 389 return ret;
390 } 390 }
391 391
392 static int netxbig_led_remove(struct platform_device *pdev) 392 static int netxbig_led_remove(struct platform_device *pdev)
393 { 393 {
394 struct netxbig_led_platform_data *pdata = pdev->dev.platform_data; 394 struct netxbig_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
395 struct netxbig_led_data *leds_data; 395 struct netxbig_led_data *leds_data;
396 int i; 396 int i;
397 397
398 leds_data = platform_get_drvdata(pdev); 398 leds_data = platform_get_drvdata(pdev);
399 399
400 for (i = 0; i < pdata->num_leds; i++) 400 for (i = 0; i < pdata->num_leds; i++)
401 delete_netxbig_led(&leds_data[i]); 401 delete_netxbig_led(&leds_data[i]);
402 402
403 gpio_ext_free(pdata->gpio_ext); 403 gpio_ext_free(pdata->gpio_ext);
404 404
405 return 0; 405 return 0;
406 } 406 }
407 407
408 static struct platform_driver netxbig_led_driver = { 408 static struct platform_driver netxbig_led_driver = {
409 .probe = netxbig_led_probe, 409 .probe = netxbig_led_probe,
410 .remove = netxbig_led_remove, 410 .remove = netxbig_led_remove,
411 .driver = { 411 .driver = {
412 .name = "leds-netxbig", 412 .name = "leds-netxbig",
413 .owner = THIS_MODULE, 413 .owner = THIS_MODULE,
414 }, 414 },
415 }; 415 };
416 416
417 module_platform_driver(netxbig_led_driver); 417 module_platform_driver(netxbig_led_driver);
418 418
419 MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); 419 MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
420 MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards"); 420 MODULE_DESCRIPTION("LED driver for LaCie xBig Network boards");
421 MODULE_LICENSE("GPL"); 421 MODULE_LICENSE("GPL");
422 MODULE_ALIAS("platform:leds-netxbig"); 422 MODULE_ALIAS("platform:leds-netxbig");
423 423
drivers/leds/leds-ns2.c
1 /* 1 /*
2 * leds-ns2.c - Driver for the Network Space v2 (and parents) dual-GPIO LED 2 * leds-ns2.c - Driver for the Network Space v2 (and parents) dual-GPIO LED
3 * 3 *
4 * Copyright (C) 2010 LaCie 4 * Copyright (C) 2010 LaCie
5 * 5 *
6 * Author: Simon Guinot <sguinot@lacie.com> 6 * Author: Simon Guinot <sguinot@lacie.com>
7 * 7 *
8 * Based on leds-gpio.c by Raphael Assenat <raph@8d.com> 8 * Based on leds-gpio.c by Raphael Assenat <raph@8d.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or 12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version. 13 * (at your option) any later version.
14 * 14 *
15 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details. 18 * GNU General Public License for more details.
19 * 19 *
20 * You should have received a copy of the GNU General Public License 20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software 21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */ 23 */
24 24
25 #include <linux/kernel.h> 25 #include <linux/kernel.h>
26 #include <linux/init.h> 26 #include <linux/init.h>
27 #include <linux/platform_device.h> 27 #include <linux/platform_device.h>
28 #include <linux/slab.h> 28 #include <linux/slab.h>
29 #include <linux/gpio.h> 29 #include <linux/gpio.h>
30 #include <linux/leds.h> 30 #include <linux/leds.h>
31 #include <linux/module.h> 31 #include <linux/module.h>
32 #include <linux/platform_data/leds-kirkwood-ns2.h> 32 #include <linux/platform_data/leds-kirkwood-ns2.h>
33 #include <linux/of_gpio.h> 33 #include <linux/of_gpio.h>
34 34
35 /* 35 /*
36 * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in 36 * The Network Space v2 dual-GPIO LED is wired to a CPLD and can blink in
37 * relation with the SATA activity. This capability is exposed through the 37 * relation with the SATA activity. This capability is exposed through the
38 * "sata" sysfs attribute. 38 * "sata" sysfs attribute.
39 * 39 *
40 * The following array detail the different LED registers and the combination 40 * The following array detail the different LED registers and the combination
41 * of their possible values: 41 * of their possible values:
42 * 42 *
43 * cmd_led | slow_led | /SATA active | LED state 43 * cmd_led | slow_led | /SATA active | LED state
44 * | | | 44 * | | |
45 * 1 | 0 | x | off 45 * 1 | 0 | x | off
46 * - | 1 | x | on 46 * - | 1 | x | on
47 * 0 | 0 | 1 | on 47 * 0 | 0 | 1 | on
48 * 0 | 0 | 0 | blink (rate 300ms) 48 * 0 | 0 | 0 | blink (rate 300ms)
49 */ 49 */
50 50
51 enum ns2_led_modes { 51 enum ns2_led_modes {
52 NS_V2_LED_OFF, 52 NS_V2_LED_OFF,
53 NS_V2_LED_ON, 53 NS_V2_LED_ON,
54 NS_V2_LED_SATA, 54 NS_V2_LED_SATA,
55 }; 55 };
56 56
57 struct ns2_led_mode_value { 57 struct ns2_led_mode_value {
58 enum ns2_led_modes mode; 58 enum ns2_led_modes mode;
59 int cmd_level; 59 int cmd_level;
60 int slow_level; 60 int slow_level;
61 }; 61 };
62 62
63 static struct ns2_led_mode_value ns2_led_modval[] = { 63 static struct ns2_led_mode_value ns2_led_modval[] = {
64 { NS_V2_LED_OFF , 1, 0 }, 64 { NS_V2_LED_OFF , 1, 0 },
65 { NS_V2_LED_ON , 0, 1 }, 65 { NS_V2_LED_ON , 0, 1 },
66 { NS_V2_LED_ON , 1, 1 }, 66 { NS_V2_LED_ON , 1, 1 },
67 { NS_V2_LED_SATA, 0, 0 }, 67 { NS_V2_LED_SATA, 0, 0 },
68 }; 68 };
69 69
70 struct ns2_led_data { 70 struct ns2_led_data {
71 struct led_classdev cdev; 71 struct led_classdev cdev;
72 unsigned cmd; 72 unsigned cmd;
73 unsigned slow; 73 unsigned slow;
74 unsigned char sata; /* True when SATA mode active. */ 74 unsigned char sata; /* True when SATA mode active. */
75 rwlock_t rw_lock; /* Lock GPIOs. */ 75 rwlock_t rw_lock; /* Lock GPIOs. */
76 }; 76 };
77 77
78 static int ns2_led_get_mode(struct ns2_led_data *led_dat, 78 static int ns2_led_get_mode(struct ns2_led_data *led_dat,
79 enum ns2_led_modes *mode) 79 enum ns2_led_modes *mode)
80 { 80 {
81 int i; 81 int i;
82 int ret = -EINVAL; 82 int ret = -EINVAL;
83 int cmd_level; 83 int cmd_level;
84 int slow_level; 84 int slow_level;
85 85
86 read_lock_irq(&led_dat->rw_lock); 86 read_lock_irq(&led_dat->rw_lock);
87 87
88 cmd_level = gpio_get_value(led_dat->cmd); 88 cmd_level = gpio_get_value(led_dat->cmd);
89 slow_level = gpio_get_value(led_dat->slow); 89 slow_level = gpio_get_value(led_dat->slow);
90 90
91 for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) { 91 for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
92 if (cmd_level == ns2_led_modval[i].cmd_level && 92 if (cmd_level == ns2_led_modval[i].cmd_level &&
93 slow_level == ns2_led_modval[i].slow_level) { 93 slow_level == ns2_led_modval[i].slow_level) {
94 *mode = ns2_led_modval[i].mode; 94 *mode = ns2_led_modval[i].mode;
95 ret = 0; 95 ret = 0;
96 break; 96 break;
97 } 97 }
98 } 98 }
99 99
100 read_unlock_irq(&led_dat->rw_lock); 100 read_unlock_irq(&led_dat->rw_lock);
101 101
102 return ret; 102 return ret;
103 } 103 }
104 104
105 static void ns2_led_set_mode(struct ns2_led_data *led_dat, 105 static void ns2_led_set_mode(struct ns2_led_data *led_dat,
106 enum ns2_led_modes mode) 106 enum ns2_led_modes mode)
107 { 107 {
108 int i; 108 int i;
109 unsigned long flags; 109 unsigned long flags;
110 110
111 write_lock_irqsave(&led_dat->rw_lock, flags); 111 write_lock_irqsave(&led_dat->rw_lock, flags);
112 112
113 for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) { 113 for (i = 0; i < ARRAY_SIZE(ns2_led_modval); i++) {
114 if (mode == ns2_led_modval[i].mode) { 114 if (mode == ns2_led_modval[i].mode) {
115 gpio_set_value(led_dat->cmd, 115 gpio_set_value(led_dat->cmd,
116 ns2_led_modval[i].cmd_level); 116 ns2_led_modval[i].cmd_level);
117 gpio_set_value(led_dat->slow, 117 gpio_set_value(led_dat->slow,
118 ns2_led_modval[i].slow_level); 118 ns2_led_modval[i].slow_level);
119 } 119 }
120 } 120 }
121 121
122 write_unlock_irqrestore(&led_dat->rw_lock, flags); 122 write_unlock_irqrestore(&led_dat->rw_lock, flags);
123 } 123 }
124 124
125 static void ns2_led_set(struct led_classdev *led_cdev, 125 static void ns2_led_set(struct led_classdev *led_cdev,
126 enum led_brightness value) 126 enum led_brightness value)
127 { 127 {
128 struct ns2_led_data *led_dat = 128 struct ns2_led_data *led_dat =
129 container_of(led_cdev, struct ns2_led_data, cdev); 129 container_of(led_cdev, struct ns2_led_data, cdev);
130 enum ns2_led_modes mode; 130 enum ns2_led_modes mode;
131 131
132 if (value == LED_OFF) 132 if (value == LED_OFF)
133 mode = NS_V2_LED_OFF; 133 mode = NS_V2_LED_OFF;
134 else if (led_dat->sata) 134 else if (led_dat->sata)
135 mode = NS_V2_LED_SATA; 135 mode = NS_V2_LED_SATA;
136 else 136 else
137 mode = NS_V2_LED_ON; 137 mode = NS_V2_LED_ON;
138 138
139 ns2_led_set_mode(led_dat, mode); 139 ns2_led_set_mode(led_dat, mode);
140 } 140 }
141 141
142 static ssize_t ns2_led_sata_store(struct device *dev, 142 static ssize_t ns2_led_sata_store(struct device *dev,
143 struct device_attribute *attr, 143 struct device_attribute *attr,
144 const char *buff, size_t count) 144 const char *buff, size_t count)
145 { 145 {
146 struct led_classdev *led_cdev = dev_get_drvdata(dev); 146 struct led_classdev *led_cdev = dev_get_drvdata(dev);
147 struct ns2_led_data *led_dat = 147 struct ns2_led_data *led_dat =
148 container_of(led_cdev, struct ns2_led_data, cdev); 148 container_of(led_cdev, struct ns2_led_data, cdev);
149 int ret; 149 int ret;
150 unsigned long enable; 150 unsigned long enable;
151 enum ns2_led_modes mode; 151 enum ns2_led_modes mode;
152 152
153 ret = kstrtoul(buff, 10, &enable); 153 ret = kstrtoul(buff, 10, &enable);
154 if (ret < 0) 154 if (ret < 0)
155 return ret; 155 return ret;
156 156
157 enable = !!enable; 157 enable = !!enable;
158 158
159 if (led_dat->sata == enable) 159 if (led_dat->sata == enable)
160 return count; 160 return count;
161 161
162 ret = ns2_led_get_mode(led_dat, &mode); 162 ret = ns2_led_get_mode(led_dat, &mode);
163 if (ret < 0) 163 if (ret < 0)
164 return ret; 164 return ret;
165 165
166 if (enable && mode == NS_V2_LED_ON) 166 if (enable && mode == NS_V2_LED_ON)
167 ns2_led_set_mode(led_dat, NS_V2_LED_SATA); 167 ns2_led_set_mode(led_dat, NS_V2_LED_SATA);
168 if (!enable && mode == NS_V2_LED_SATA) 168 if (!enable && mode == NS_V2_LED_SATA)
169 ns2_led_set_mode(led_dat, NS_V2_LED_ON); 169 ns2_led_set_mode(led_dat, NS_V2_LED_ON);
170 170
171 led_dat->sata = enable; 171 led_dat->sata = enable;
172 172
173 return count; 173 return count;
174 } 174 }
175 175
176 static ssize_t ns2_led_sata_show(struct device *dev, 176 static ssize_t ns2_led_sata_show(struct device *dev,
177 struct device_attribute *attr, char *buf) 177 struct device_attribute *attr, char *buf)
178 { 178 {
179 struct led_classdev *led_cdev = dev_get_drvdata(dev); 179 struct led_classdev *led_cdev = dev_get_drvdata(dev);
180 struct ns2_led_data *led_dat = 180 struct ns2_led_data *led_dat =
181 container_of(led_cdev, struct ns2_led_data, cdev); 181 container_of(led_cdev, struct ns2_led_data, cdev);
182 182
183 return sprintf(buf, "%d\n", led_dat->sata); 183 return sprintf(buf, "%d\n", led_dat->sata);
184 } 184 }
185 185
186 static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store); 186 static DEVICE_ATTR(sata, 0644, ns2_led_sata_show, ns2_led_sata_store);
187 187
188 static int 188 static int
189 create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat, 189 create_ns2_led(struct platform_device *pdev, struct ns2_led_data *led_dat,
190 const struct ns2_led *template) 190 const struct ns2_led *template)
191 { 191 {
192 int ret; 192 int ret;
193 enum ns2_led_modes mode; 193 enum ns2_led_modes mode;
194 194
195 ret = devm_gpio_request_one(&pdev->dev, template->cmd, 195 ret = devm_gpio_request_one(&pdev->dev, template->cmd,
196 gpio_get_value(template->cmd) ? 196 gpio_get_value(template->cmd) ?
197 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, 197 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
198 template->name); 198 template->name);
199 if (ret) { 199 if (ret) {
200 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n", 200 dev_err(&pdev->dev, "%s: failed to setup command GPIO\n",
201 template->name); 201 template->name);
202 return ret; 202 return ret;
203 } 203 }
204 204
205 ret = devm_gpio_request_one(&pdev->dev, template->slow, 205 ret = devm_gpio_request_one(&pdev->dev, template->slow,
206 gpio_get_value(template->slow) ? 206 gpio_get_value(template->slow) ?
207 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, 207 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
208 template->name); 208 template->name);
209 if (ret) { 209 if (ret) {
210 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n", 210 dev_err(&pdev->dev, "%s: failed to setup slow GPIO\n",
211 template->name); 211 template->name);
212 return ret; 212 return ret;
213 } 213 }
214 214
215 rwlock_init(&led_dat->rw_lock); 215 rwlock_init(&led_dat->rw_lock);
216 216
217 led_dat->cdev.name = template->name; 217 led_dat->cdev.name = template->name;
218 led_dat->cdev.default_trigger = template->default_trigger; 218 led_dat->cdev.default_trigger = template->default_trigger;
219 led_dat->cdev.blink_set = NULL; 219 led_dat->cdev.blink_set = NULL;
220 led_dat->cdev.brightness_set = ns2_led_set; 220 led_dat->cdev.brightness_set = ns2_led_set;
221 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 221 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
222 led_dat->cmd = template->cmd; 222 led_dat->cmd = template->cmd;
223 led_dat->slow = template->slow; 223 led_dat->slow = template->slow;
224 224
225 ret = ns2_led_get_mode(led_dat, &mode); 225 ret = ns2_led_get_mode(led_dat, &mode);
226 if (ret < 0) 226 if (ret < 0)
227 return ret; 227 return ret;
228 228
229 /* Set LED initial state. */ 229 /* Set LED initial state. */
230 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0; 230 led_dat->sata = (mode == NS_V2_LED_SATA) ? 1 : 0;
231 led_dat->cdev.brightness = 231 led_dat->cdev.brightness =
232 (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL; 232 (mode == NS_V2_LED_OFF) ? LED_OFF : LED_FULL;
233 233
234 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 234 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
235 if (ret < 0) 235 if (ret < 0)
236 return ret; 236 return ret;
237 237
238 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata); 238 ret = device_create_file(led_dat->cdev.dev, &dev_attr_sata);
239 if (ret < 0) 239 if (ret < 0)
240 goto err_free_cdev; 240 goto err_free_cdev;
241 241
242 return 0; 242 return 0;
243 243
244 err_free_cdev: 244 err_free_cdev:
245 led_classdev_unregister(&led_dat->cdev); 245 led_classdev_unregister(&led_dat->cdev);
246 return ret; 246 return ret;
247 } 247 }
248 248
249 static void delete_ns2_led(struct ns2_led_data *led_dat) 249 static void delete_ns2_led(struct ns2_led_data *led_dat)
250 { 250 {
251 device_remove_file(led_dat->cdev.dev, &dev_attr_sata); 251 device_remove_file(led_dat->cdev.dev, &dev_attr_sata);
252 led_classdev_unregister(&led_dat->cdev); 252 led_classdev_unregister(&led_dat->cdev);
253 } 253 }
254 254
255 #ifdef CONFIG_OF_GPIO 255 #ifdef CONFIG_OF_GPIO
256 /* 256 /*
257 * Translate OpenFirmware node properties into platform_data. 257 * Translate OpenFirmware node properties into platform_data.
258 */ 258 */
259 static int 259 static int
260 ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata) 260 ns2_leds_get_of_pdata(struct device *dev, struct ns2_led_platform_data *pdata)
261 { 261 {
262 struct device_node *np = dev->of_node; 262 struct device_node *np = dev->of_node;
263 struct device_node *child; 263 struct device_node *child;
264 struct ns2_led *leds; 264 struct ns2_led *leds;
265 int num_leds = 0; 265 int num_leds = 0;
266 int i = 0; 266 int i = 0;
267 267
268 num_leds = of_get_child_count(np); 268 num_leds = of_get_child_count(np);
269 if (!num_leds) 269 if (!num_leds)
270 return -ENODEV; 270 return -ENODEV;
271 271
272 leds = devm_kzalloc(dev, num_leds * sizeof(struct ns2_led), 272 leds = devm_kzalloc(dev, num_leds * sizeof(struct ns2_led),
273 GFP_KERNEL); 273 GFP_KERNEL);
274 if (!leds) 274 if (!leds)
275 return -ENOMEM; 275 return -ENOMEM;
276 276
277 for_each_child_of_node(np, child) { 277 for_each_child_of_node(np, child) {
278 const char *string; 278 const char *string;
279 int ret; 279 int ret;
280 280
281 ret = of_get_named_gpio(child, "cmd-gpio", 0); 281 ret = of_get_named_gpio(child, "cmd-gpio", 0);
282 if (ret < 0) 282 if (ret < 0)
283 return ret; 283 return ret;
284 leds[i].cmd = ret; 284 leds[i].cmd = ret;
285 ret = of_get_named_gpio(child, "slow-gpio", 0); 285 ret = of_get_named_gpio(child, "slow-gpio", 0);
286 if (ret < 0) 286 if (ret < 0)
287 return ret; 287 return ret;
288 leds[i].slow = ret; 288 leds[i].slow = ret;
289 ret = of_property_read_string(child, "label", &string); 289 ret = of_property_read_string(child, "label", &string);
290 leds[i].name = (ret == 0) ? string : child->name; 290 leds[i].name = (ret == 0) ? string : child->name;
291 ret = of_property_read_string(child, "linux,default-trigger", 291 ret = of_property_read_string(child, "linux,default-trigger",
292 &string); 292 &string);
293 if (ret == 0) 293 if (ret == 0)
294 leds[i].default_trigger = string; 294 leds[i].default_trigger = string;
295 295
296 i++; 296 i++;
297 } 297 }
298 298
299 pdata->leds = leds; 299 pdata->leds = leds;
300 pdata->num_leds = num_leds; 300 pdata->num_leds = num_leds;
301 301
302 return 0; 302 return 0;
303 } 303 }
304 304
305 static const struct of_device_id of_ns2_leds_match[] = { 305 static const struct of_device_id of_ns2_leds_match[] = {
306 { .compatible = "lacie,ns2-leds", }, 306 { .compatible = "lacie,ns2-leds", },
307 {}, 307 {},
308 }; 308 };
309 #endif /* CONFIG_OF_GPIO */ 309 #endif /* CONFIG_OF_GPIO */
310 310
311 struct ns2_led_priv { 311 struct ns2_led_priv {
312 int num_leds; 312 int num_leds;
313 struct ns2_led_data leds_data[]; 313 struct ns2_led_data leds_data[];
314 }; 314 };
315 315
316 static inline int sizeof_ns2_led_priv(int num_leds) 316 static inline int sizeof_ns2_led_priv(int num_leds)
317 { 317 {
318 return sizeof(struct ns2_led_priv) + 318 return sizeof(struct ns2_led_priv) +
319 (sizeof(struct ns2_led_data) * num_leds); 319 (sizeof(struct ns2_led_data) * num_leds);
320 } 320 }
321 321
322 static int ns2_led_probe(struct platform_device *pdev) 322 static int ns2_led_probe(struct platform_device *pdev)
323 { 323 {
324 struct ns2_led_platform_data *pdata = pdev->dev.platform_data; 324 struct ns2_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
325 struct ns2_led_priv *priv; 325 struct ns2_led_priv *priv;
326 int i; 326 int i;
327 int ret; 327 int ret;
328 328
329 #ifdef CONFIG_OF_GPIO 329 #ifdef CONFIG_OF_GPIO
330 if (!pdata) { 330 if (!pdata) {
331 pdata = devm_kzalloc(&pdev->dev, 331 pdata = devm_kzalloc(&pdev->dev,
332 sizeof(struct ns2_led_platform_data), 332 sizeof(struct ns2_led_platform_data),
333 GFP_KERNEL); 333 GFP_KERNEL);
334 if (!pdata) 334 if (!pdata)
335 return -ENOMEM; 335 return -ENOMEM;
336 336
337 ret = ns2_leds_get_of_pdata(&pdev->dev, pdata); 337 ret = ns2_leds_get_of_pdata(&pdev->dev, pdata);
338 if (ret) 338 if (ret)
339 return ret; 339 return ret;
340 } 340 }
341 #else 341 #else
342 if (!pdata) 342 if (!pdata)
343 return -EINVAL; 343 return -EINVAL;
344 #endif /* CONFIG_OF_GPIO */ 344 #endif /* CONFIG_OF_GPIO */
345 345
346 priv = devm_kzalloc(&pdev->dev, 346 priv = devm_kzalloc(&pdev->dev,
347 sizeof_ns2_led_priv(pdata->num_leds), GFP_KERNEL); 347 sizeof_ns2_led_priv(pdata->num_leds), GFP_KERNEL);
348 if (!priv) 348 if (!priv)
349 return -ENOMEM; 349 return -ENOMEM;
350 priv->num_leds = pdata->num_leds; 350 priv->num_leds = pdata->num_leds;
351 351
352 for (i = 0; i < priv->num_leds; i++) { 352 for (i = 0; i < priv->num_leds; i++) {
353 ret = create_ns2_led(pdev, &priv->leds_data[i], 353 ret = create_ns2_led(pdev, &priv->leds_data[i],
354 &pdata->leds[i]); 354 &pdata->leds[i]);
355 if (ret < 0) { 355 if (ret < 0) {
356 for (i = i - 1; i >= 0; i--) 356 for (i = i - 1; i >= 0; i--)
357 delete_ns2_led(&priv->leds_data[i]); 357 delete_ns2_led(&priv->leds_data[i]);
358 return ret; 358 return ret;
359 } 359 }
360 } 360 }
361 361
362 platform_set_drvdata(pdev, priv); 362 platform_set_drvdata(pdev, priv);
363 363
364 return 0; 364 return 0;
365 } 365 }
366 366
367 static int ns2_led_remove(struct platform_device *pdev) 367 static int ns2_led_remove(struct platform_device *pdev)
368 { 368 {
369 int i; 369 int i;
370 struct ns2_led_priv *priv; 370 struct ns2_led_priv *priv;
371 371
372 priv = platform_get_drvdata(pdev); 372 priv = platform_get_drvdata(pdev);
373 373
374 for (i = 0; i < priv->num_leds; i++) 374 for (i = 0; i < priv->num_leds; i++)
375 delete_ns2_led(&priv->leds_data[i]); 375 delete_ns2_led(&priv->leds_data[i]);
376 376
377 return 0; 377 return 0;
378 } 378 }
379 379
380 static struct platform_driver ns2_led_driver = { 380 static struct platform_driver ns2_led_driver = {
381 .probe = ns2_led_probe, 381 .probe = ns2_led_probe,
382 .remove = ns2_led_remove, 382 .remove = ns2_led_remove,
383 .driver = { 383 .driver = {
384 .name = "leds-ns2", 384 .name = "leds-ns2",
385 .owner = THIS_MODULE, 385 .owner = THIS_MODULE,
386 .of_match_table = of_match_ptr(of_ns2_leds_match), 386 .of_match_table = of_match_ptr(of_ns2_leds_match),
387 }, 387 },
388 }; 388 };
389 389
390 module_platform_driver(ns2_led_driver); 390 module_platform_driver(ns2_led_driver);
391 391
392 MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>"); 392 MODULE_AUTHOR("Simon Guinot <sguinot@lacie.com>");
393 MODULE_DESCRIPTION("Network Space v2 LED driver"); 393 MODULE_DESCRIPTION("Network Space v2 LED driver");
394 MODULE_LICENSE("GPL"); 394 MODULE_LICENSE("GPL");
395 MODULE_ALIAS("platform:leds-ns2"); 395 MODULE_ALIAS("platform:leds-ns2");
396 396
drivers/leds/leds-pca9532.c
1 /* 1 /*
2 * pca9532.c - 16-bit Led dimmer 2 * pca9532.c - 16-bit Led dimmer
3 * 3 *
4 * Copyright (C) 2011 Jan Weitzel 4 * Copyright (C) 2011 Jan Weitzel
5 * Copyright (C) 2008 Riku Voipio 5 * Copyright (C) 2008 Riku Voipio
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License. 9 * the Free Software Foundation; version 2 of the License.
10 * 10 *
11 * Datasheet: http://www.nxp.com/documents/data_sheet/PCA9532.pdf 11 * Datasheet: http://www.nxp.com/documents/data_sheet/PCA9532.pdf
12 * 12 *
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/i2c.h> 16 #include <linux/i2c.h>
17 #include <linux/slab.h> 17 #include <linux/slab.h>
18 #include <linux/leds.h> 18 #include <linux/leds.h>
19 #include <linux/input.h> 19 #include <linux/input.h>
20 #include <linux/mutex.h> 20 #include <linux/mutex.h>
21 #include <linux/workqueue.h> 21 #include <linux/workqueue.h>
22 #include <linux/leds-pca9532.h> 22 #include <linux/leds-pca9532.h>
23 #include <linux/gpio.h> 23 #include <linux/gpio.h>
24 24
25 /* m = num_leds*/ 25 /* m = num_leds*/
26 #define PCA9532_REG_INPUT(i) ((i) >> 3) 26 #define PCA9532_REG_INPUT(i) ((i) >> 3)
27 #define PCA9532_REG_OFFSET(m) ((m) >> 4) 27 #define PCA9532_REG_OFFSET(m) ((m) >> 4)
28 #define PCA9532_REG_PSC(m, i) (PCA9532_REG_OFFSET(m) + 0x1 + (i) * 2) 28 #define PCA9532_REG_PSC(m, i) (PCA9532_REG_OFFSET(m) + 0x1 + (i) * 2)
29 #define PCA9532_REG_PWM(m, i) (PCA9532_REG_OFFSET(m) + 0x2 + (i) * 2) 29 #define PCA9532_REG_PWM(m, i) (PCA9532_REG_OFFSET(m) + 0x2 + (i) * 2)
30 #define LED_REG(m, led) (PCA9532_REG_OFFSET(m) + 0x5 + (led >> 2)) 30 #define LED_REG(m, led) (PCA9532_REG_OFFSET(m) + 0x5 + (led >> 2))
31 #define LED_NUM(led) (led & 0x3) 31 #define LED_NUM(led) (led & 0x3)
32 32
33 #define ldev_to_led(c) container_of(c, struct pca9532_led, ldev) 33 #define ldev_to_led(c) container_of(c, struct pca9532_led, ldev)
34 34
35 struct pca9532_chip_info { 35 struct pca9532_chip_info {
36 u8 num_leds; 36 u8 num_leds;
37 }; 37 };
38 38
39 struct pca9532_data { 39 struct pca9532_data {
40 struct i2c_client *client; 40 struct i2c_client *client;
41 struct pca9532_led leds[16]; 41 struct pca9532_led leds[16];
42 struct mutex update_lock; 42 struct mutex update_lock;
43 struct input_dev *idev; 43 struct input_dev *idev;
44 struct work_struct work; 44 struct work_struct work;
45 #ifdef CONFIG_LEDS_PCA9532_GPIO 45 #ifdef CONFIG_LEDS_PCA9532_GPIO
46 struct gpio_chip gpio; 46 struct gpio_chip gpio;
47 #endif 47 #endif
48 const struct pca9532_chip_info *chip_info; 48 const struct pca9532_chip_info *chip_info;
49 u8 pwm[2]; 49 u8 pwm[2];
50 u8 psc[2]; 50 u8 psc[2];
51 }; 51 };
52 52
53 static int pca9532_probe(struct i2c_client *client, 53 static int pca9532_probe(struct i2c_client *client,
54 const struct i2c_device_id *id); 54 const struct i2c_device_id *id);
55 static int pca9532_remove(struct i2c_client *client); 55 static int pca9532_remove(struct i2c_client *client);
56 56
57 enum { 57 enum {
58 pca9530, 58 pca9530,
59 pca9531, 59 pca9531,
60 pca9532, 60 pca9532,
61 pca9533, 61 pca9533,
62 }; 62 };
63 63
64 static const struct i2c_device_id pca9532_id[] = { 64 static const struct i2c_device_id pca9532_id[] = {
65 { "pca9530", pca9530 }, 65 { "pca9530", pca9530 },
66 { "pca9531", pca9531 }, 66 { "pca9531", pca9531 },
67 { "pca9532", pca9532 }, 67 { "pca9532", pca9532 },
68 { "pca9533", pca9533 }, 68 { "pca9533", pca9533 },
69 { } 69 { }
70 }; 70 };
71 71
72 MODULE_DEVICE_TABLE(i2c, pca9532_id); 72 MODULE_DEVICE_TABLE(i2c, pca9532_id);
73 73
74 static const struct pca9532_chip_info pca9532_chip_info_tbl[] = { 74 static const struct pca9532_chip_info pca9532_chip_info_tbl[] = {
75 [pca9530] = { 75 [pca9530] = {
76 .num_leds = 2, 76 .num_leds = 2,
77 }, 77 },
78 [pca9531] = { 78 [pca9531] = {
79 .num_leds = 8, 79 .num_leds = 8,
80 }, 80 },
81 [pca9532] = { 81 [pca9532] = {
82 .num_leds = 16, 82 .num_leds = 16,
83 }, 83 },
84 [pca9533] = { 84 [pca9533] = {
85 .num_leds = 4, 85 .num_leds = 4,
86 }, 86 },
87 }; 87 };
88 88
89 static struct i2c_driver pca9532_driver = { 89 static struct i2c_driver pca9532_driver = {
90 .driver = { 90 .driver = {
91 .name = "leds-pca953x", 91 .name = "leds-pca953x",
92 }, 92 },
93 .probe = pca9532_probe, 93 .probe = pca9532_probe,
94 .remove = pca9532_remove, 94 .remove = pca9532_remove,
95 .id_table = pca9532_id, 95 .id_table = pca9532_id,
96 }; 96 };
97 97
98 /* We have two pwm/blinkers, but 16 possible leds to drive. Additionally, 98 /* We have two pwm/blinkers, but 16 possible leds to drive. Additionally,
99 * the clever Thecus people are using one pwm to drive the beeper. So, 99 * the clever Thecus people are using one pwm to drive the beeper. So,
100 * as a compromise we average one pwm to the values requested by all 100 * as a compromise we average one pwm to the values requested by all
101 * leds that are not ON/OFF. 101 * leds that are not ON/OFF.
102 * */ 102 * */
103 static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink, 103 static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink,
104 enum led_brightness value) 104 enum led_brightness value)
105 { 105 {
106 int a = 0, b = 0, i = 0; 106 int a = 0, b = 0, i = 0;
107 struct pca9532_data *data = i2c_get_clientdata(client); 107 struct pca9532_data *data = i2c_get_clientdata(client);
108 for (i = 0; i < data->chip_info->num_leds; i++) { 108 for (i = 0; i < data->chip_info->num_leds; i++) {
109 if (data->leds[i].type == PCA9532_TYPE_LED && 109 if (data->leds[i].type == PCA9532_TYPE_LED &&
110 data->leds[i].state == PCA9532_PWM0+pwm) { 110 data->leds[i].state == PCA9532_PWM0+pwm) {
111 a++; 111 a++;
112 b += data->leds[i].ldev.brightness; 112 b += data->leds[i].ldev.brightness;
113 } 113 }
114 } 114 }
115 if (a == 0) { 115 if (a == 0) {
116 dev_err(&client->dev, 116 dev_err(&client->dev,
117 "fear of division by zero %d/%d, wanted %d\n", 117 "fear of division by zero %d/%d, wanted %d\n",
118 b, a, value); 118 b, a, value);
119 return -EINVAL; 119 return -EINVAL;
120 } 120 }
121 b = b/a; 121 b = b/a;
122 if (b > 0xFF) 122 if (b > 0xFF)
123 return -EINVAL; 123 return -EINVAL;
124 data->pwm[pwm] = b; 124 data->pwm[pwm] = b;
125 data->psc[pwm] = blink; 125 data->psc[pwm] = blink;
126 return 0; 126 return 0;
127 } 127 }
128 128
129 static int pca9532_setpwm(struct i2c_client *client, int pwm) 129 static int pca9532_setpwm(struct i2c_client *client, int pwm)
130 { 130 {
131 struct pca9532_data *data = i2c_get_clientdata(client); 131 struct pca9532_data *data = i2c_get_clientdata(client);
132 u8 maxleds = data->chip_info->num_leds; 132 u8 maxleds = data->chip_info->num_leds;
133 133
134 mutex_lock(&data->update_lock); 134 mutex_lock(&data->update_lock);
135 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, pwm), 135 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, pwm),
136 data->pwm[pwm]); 136 data->pwm[pwm]);
137 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, pwm), 137 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, pwm),
138 data->psc[pwm]); 138 data->psc[pwm]);
139 mutex_unlock(&data->update_lock); 139 mutex_unlock(&data->update_lock);
140 return 0; 140 return 0;
141 } 141 }
142 142
143 /* Set LED routing */ 143 /* Set LED routing */
144 static void pca9532_setled(struct pca9532_led *led) 144 static void pca9532_setled(struct pca9532_led *led)
145 { 145 {
146 struct i2c_client *client = led->client; 146 struct i2c_client *client = led->client;
147 struct pca9532_data *data = i2c_get_clientdata(client); 147 struct pca9532_data *data = i2c_get_clientdata(client);
148 u8 maxleds = data->chip_info->num_leds; 148 u8 maxleds = data->chip_info->num_leds;
149 char reg; 149 char reg;
150 150
151 mutex_lock(&data->update_lock); 151 mutex_lock(&data->update_lock);
152 reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id)); 152 reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id));
153 /* zero led bits */ 153 /* zero led bits */
154 reg = reg & ~(0x3<<LED_NUM(led->id)*2); 154 reg = reg & ~(0x3<<LED_NUM(led->id)*2);
155 /* set the new value */ 155 /* set the new value */
156 reg = reg | (led->state << LED_NUM(led->id)*2); 156 reg = reg | (led->state << LED_NUM(led->id)*2);
157 i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg); 157 i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg);
158 mutex_unlock(&data->update_lock); 158 mutex_unlock(&data->update_lock);
159 } 159 }
160 160
161 static void pca9532_set_brightness(struct led_classdev *led_cdev, 161 static void pca9532_set_brightness(struct led_classdev *led_cdev,
162 enum led_brightness value) 162 enum led_brightness value)
163 { 163 {
164 int err = 0; 164 int err = 0;
165 struct pca9532_led *led = ldev_to_led(led_cdev); 165 struct pca9532_led *led = ldev_to_led(led_cdev);
166 166
167 if (value == LED_OFF) 167 if (value == LED_OFF)
168 led->state = PCA9532_OFF; 168 led->state = PCA9532_OFF;
169 else if (value == LED_FULL) 169 else if (value == LED_FULL)
170 led->state = PCA9532_ON; 170 led->state = PCA9532_ON;
171 else { 171 else {
172 led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */ 172 led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */
173 err = pca9532_calcpwm(led->client, 0, 0, value); 173 err = pca9532_calcpwm(led->client, 0, 0, value);
174 if (err) 174 if (err)
175 return; /* XXX: led api doesn't allow error code? */ 175 return; /* XXX: led api doesn't allow error code? */
176 } 176 }
177 schedule_work(&led->work); 177 schedule_work(&led->work);
178 } 178 }
179 179
180 static int pca9532_set_blink(struct led_classdev *led_cdev, 180 static int pca9532_set_blink(struct led_classdev *led_cdev,
181 unsigned long *delay_on, unsigned long *delay_off) 181 unsigned long *delay_on, unsigned long *delay_off)
182 { 182 {
183 struct pca9532_led *led = ldev_to_led(led_cdev); 183 struct pca9532_led *led = ldev_to_led(led_cdev);
184 struct i2c_client *client = led->client; 184 struct i2c_client *client = led->client;
185 int psc; 185 int psc;
186 int err = 0; 186 int err = 0;
187 187
188 if (*delay_on == 0 && *delay_off == 0) { 188 if (*delay_on == 0 && *delay_off == 0) {
189 /* led subsystem ask us for a blink rate */ 189 /* led subsystem ask us for a blink rate */
190 *delay_on = 1000; 190 *delay_on = 1000;
191 *delay_off = 1000; 191 *delay_off = 1000;
192 } 192 }
193 if (*delay_on != *delay_off || *delay_on > 1690 || *delay_on < 6) 193 if (*delay_on != *delay_off || *delay_on > 1690 || *delay_on < 6)
194 return -EINVAL; 194 return -EINVAL;
195 195
196 /* Thecus specific: only use PSC/PWM 0 */ 196 /* Thecus specific: only use PSC/PWM 0 */
197 psc = (*delay_on * 152-1)/1000; 197 psc = (*delay_on * 152-1)/1000;
198 err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness); 198 err = pca9532_calcpwm(client, 0, psc, led_cdev->brightness);
199 if (err) 199 if (err)
200 return err; 200 return err;
201 schedule_work(&led->work); 201 schedule_work(&led->work);
202 return 0; 202 return 0;
203 } 203 }
204 204
205 static int pca9532_event(struct input_dev *dev, unsigned int type, 205 static int pca9532_event(struct input_dev *dev, unsigned int type,
206 unsigned int code, int value) 206 unsigned int code, int value)
207 { 207 {
208 struct pca9532_data *data = input_get_drvdata(dev); 208 struct pca9532_data *data = input_get_drvdata(dev);
209 209
210 if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE))) 210 if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))
211 return -1; 211 return -1;
212 212
213 /* XXX: allow different kind of beeps with psc/pwm modifications */ 213 /* XXX: allow different kind of beeps with psc/pwm modifications */
214 if (value > 1 && value < 32767) 214 if (value > 1 && value < 32767)
215 data->pwm[1] = 127; 215 data->pwm[1] = 127;
216 else 216 else
217 data->pwm[1] = 0; 217 data->pwm[1] = 0;
218 218
219 schedule_work(&data->work); 219 schedule_work(&data->work);
220 220
221 return 0; 221 return 0;
222 } 222 }
223 223
224 static void pca9532_input_work(struct work_struct *work) 224 static void pca9532_input_work(struct work_struct *work)
225 { 225 {
226 struct pca9532_data *data = 226 struct pca9532_data *data =
227 container_of(work, struct pca9532_data, work); 227 container_of(work, struct pca9532_data, work);
228 u8 maxleds = data->chip_info->num_leds; 228 u8 maxleds = data->chip_info->num_leds;
229 229
230 mutex_lock(&data->update_lock); 230 mutex_lock(&data->update_lock);
231 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1), 231 i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1),
232 data->pwm[1]); 232 data->pwm[1]);
233 mutex_unlock(&data->update_lock); 233 mutex_unlock(&data->update_lock);
234 } 234 }
235 235
236 static void pca9532_led_work(struct work_struct *work) 236 static void pca9532_led_work(struct work_struct *work)
237 { 237 {
238 struct pca9532_led *led; 238 struct pca9532_led *led;
239 led = container_of(work, struct pca9532_led, work); 239 led = container_of(work, struct pca9532_led, work);
240 if (led->state == PCA9532_PWM0) 240 if (led->state == PCA9532_PWM0)
241 pca9532_setpwm(led->client, 0); 241 pca9532_setpwm(led->client, 0);
242 pca9532_setled(led); 242 pca9532_setled(led);
243 } 243 }
244 244
245 #ifdef CONFIG_LEDS_PCA9532_GPIO 245 #ifdef CONFIG_LEDS_PCA9532_GPIO
246 static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset) 246 static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset)
247 { 247 {
248 struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio); 248 struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio);
249 struct pca9532_led *led = &data->leds[offset]; 249 struct pca9532_led *led = &data->leds[offset];
250 250
251 if (led->type == PCA9532_TYPE_GPIO) 251 if (led->type == PCA9532_TYPE_GPIO)
252 return 0; 252 return 0;
253 253
254 return -EBUSY; 254 return -EBUSY;
255 } 255 }
256 256
257 static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val) 257 static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val)
258 { 258 {
259 struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio); 259 struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio);
260 struct pca9532_led *led = &data->leds[offset]; 260 struct pca9532_led *led = &data->leds[offset];
261 261
262 if (val) 262 if (val)
263 led->state = PCA9532_ON; 263 led->state = PCA9532_ON;
264 else 264 else
265 led->state = PCA9532_OFF; 265 led->state = PCA9532_OFF;
266 266
267 pca9532_setled(led); 267 pca9532_setled(led);
268 } 268 }
269 269
270 static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset) 270 static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset)
271 { 271 {
272 struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio); 272 struct pca9532_data *data = container_of(gc, struct pca9532_data, gpio);
273 unsigned char reg; 273 unsigned char reg;
274 274
275 reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset)); 275 reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset));
276 276
277 return !!(reg & (1 << (offset % 8))); 277 return !!(reg & (1 << (offset % 8)));
278 } 278 }
279 279
280 static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset) 280 static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset)
281 { 281 {
282 /* To use as input ensure pin is not driven */ 282 /* To use as input ensure pin is not driven */
283 pca9532_gpio_set_value(gc, offset, 0); 283 pca9532_gpio_set_value(gc, offset, 0);
284 284
285 return 0; 285 return 0;
286 } 286 }
287 287
288 static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val) 288 static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val)
289 { 289 {
290 pca9532_gpio_set_value(gc, offset, val); 290 pca9532_gpio_set_value(gc, offset, val);
291 291
292 return 0; 292 return 0;
293 } 293 }
294 #endif /* CONFIG_LEDS_PCA9532_GPIO */ 294 #endif /* CONFIG_LEDS_PCA9532_GPIO */
295 295
296 static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs) 296 static int pca9532_destroy_devices(struct pca9532_data *data, int n_devs)
297 { 297 {
298 int i = n_devs; 298 int i = n_devs;
299 299
300 if (!data) 300 if (!data)
301 return -EINVAL; 301 return -EINVAL;
302 302
303 while (--i >= 0) { 303 while (--i >= 0) {
304 switch (data->leds[i].type) { 304 switch (data->leds[i].type) {
305 case PCA9532_TYPE_NONE: 305 case PCA9532_TYPE_NONE:
306 case PCA9532_TYPE_GPIO: 306 case PCA9532_TYPE_GPIO:
307 break; 307 break;
308 case PCA9532_TYPE_LED: 308 case PCA9532_TYPE_LED:
309 led_classdev_unregister(&data->leds[i].ldev); 309 led_classdev_unregister(&data->leds[i].ldev);
310 cancel_work_sync(&data->leds[i].work); 310 cancel_work_sync(&data->leds[i].work);
311 break; 311 break;
312 case PCA9532_TYPE_N2100_BEEP: 312 case PCA9532_TYPE_N2100_BEEP:
313 if (data->idev != NULL) { 313 if (data->idev != NULL) {
314 cancel_work_sync(&data->work); 314 cancel_work_sync(&data->work);
315 data->idev = NULL; 315 data->idev = NULL;
316 } 316 }
317 break; 317 break;
318 } 318 }
319 } 319 }
320 320
321 #ifdef CONFIG_LEDS_PCA9532_GPIO 321 #ifdef CONFIG_LEDS_PCA9532_GPIO
322 if (data->gpio.dev) { 322 if (data->gpio.dev) {
323 int err = gpiochip_remove(&data->gpio); 323 int err = gpiochip_remove(&data->gpio);
324 if (err) { 324 if (err) {
325 dev_err(&data->client->dev, "%s failed, %d\n", 325 dev_err(&data->client->dev, "%s failed, %d\n",
326 "gpiochip_remove()", err); 326 "gpiochip_remove()", err);
327 return err; 327 return err;
328 } 328 }
329 } 329 }
330 #endif 330 #endif
331 331
332 return 0; 332 return 0;
333 } 333 }
334 334
335 static int pca9532_configure(struct i2c_client *client, 335 static int pca9532_configure(struct i2c_client *client,
336 struct pca9532_data *data, struct pca9532_platform_data *pdata) 336 struct pca9532_data *data, struct pca9532_platform_data *pdata)
337 { 337 {
338 int i, err = 0; 338 int i, err = 0;
339 int gpios = 0; 339 int gpios = 0;
340 u8 maxleds = data->chip_info->num_leds; 340 u8 maxleds = data->chip_info->num_leds;
341 341
342 for (i = 0; i < 2; i++) { 342 for (i = 0; i < 2; i++) {
343 data->pwm[i] = pdata->pwm[i]; 343 data->pwm[i] = pdata->pwm[i];
344 data->psc[i] = pdata->psc[i]; 344 data->psc[i] = pdata->psc[i];
345 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i), 345 i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),
346 data->pwm[i]); 346 data->pwm[i]);
347 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i), 347 i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),
348 data->psc[i]); 348 data->psc[i]);
349 } 349 }
350 350
351 for (i = 0; i < data->chip_info->num_leds; i++) { 351 for (i = 0; i < data->chip_info->num_leds; i++) {
352 struct pca9532_led *led = &data->leds[i]; 352 struct pca9532_led *led = &data->leds[i];
353 struct pca9532_led *pled = &pdata->leds[i]; 353 struct pca9532_led *pled = &pdata->leds[i];
354 led->client = client; 354 led->client = client;
355 led->id = i; 355 led->id = i;
356 led->type = pled->type; 356 led->type = pled->type;
357 switch (led->type) { 357 switch (led->type) {
358 case PCA9532_TYPE_NONE: 358 case PCA9532_TYPE_NONE:
359 break; 359 break;
360 case PCA9532_TYPE_GPIO: 360 case PCA9532_TYPE_GPIO:
361 gpios++; 361 gpios++;
362 break; 362 break;
363 case PCA9532_TYPE_LED: 363 case PCA9532_TYPE_LED:
364 led->state = pled->state; 364 led->state = pled->state;
365 led->name = pled->name; 365 led->name = pled->name;
366 led->ldev.name = led->name; 366 led->ldev.name = led->name;
367 led->ldev.brightness = LED_OFF; 367 led->ldev.brightness = LED_OFF;
368 led->ldev.brightness_set = pca9532_set_brightness; 368 led->ldev.brightness_set = pca9532_set_brightness;
369 led->ldev.blink_set = pca9532_set_blink; 369 led->ldev.blink_set = pca9532_set_blink;
370 INIT_WORK(&led->work, pca9532_led_work); 370 INIT_WORK(&led->work, pca9532_led_work);
371 err = led_classdev_register(&client->dev, &led->ldev); 371 err = led_classdev_register(&client->dev, &led->ldev);
372 if (err < 0) { 372 if (err < 0) {
373 dev_err(&client->dev, 373 dev_err(&client->dev,
374 "couldn't register LED %s\n", 374 "couldn't register LED %s\n",
375 led->name); 375 led->name);
376 goto exit; 376 goto exit;
377 } 377 }
378 pca9532_setled(led); 378 pca9532_setled(led);
379 break; 379 break;
380 case PCA9532_TYPE_N2100_BEEP: 380 case PCA9532_TYPE_N2100_BEEP:
381 BUG_ON(data->idev); 381 BUG_ON(data->idev);
382 led->state = PCA9532_PWM1; 382 led->state = PCA9532_PWM1;
383 pca9532_setled(led); 383 pca9532_setled(led);
384 data->idev = devm_input_allocate_device(&client->dev); 384 data->idev = devm_input_allocate_device(&client->dev);
385 if (data->idev == NULL) { 385 if (data->idev == NULL) {
386 err = -ENOMEM; 386 err = -ENOMEM;
387 goto exit; 387 goto exit;
388 } 388 }
389 data->idev->name = pled->name; 389 data->idev->name = pled->name;
390 data->idev->phys = "i2c/pca9532"; 390 data->idev->phys = "i2c/pca9532";
391 data->idev->id.bustype = BUS_HOST; 391 data->idev->id.bustype = BUS_HOST;
392 data->idev->id.vendor = 0x001f; 392 data->idev->id.vendor = 0x001f;
393 data->idev->id.product = 0x0001; 393 data->idev->id.product = 0x0001;
394 data->idev->id.version = 0x0100; 394 data->idev->id.version = 0x0100;
395 data->idev->evbit[0] = BIT_MASK(EV_SND); 395 data->idev->evbit[0] = BIT_MASK(EV_SND);
396 data->idev->sndbit[0] = BIT_MASK(SND_BELL) | 396 data->idev->sndbit[0] = BIT_MASK(SND_BELL) |
397 BIT_MASK(SND_TONE); 397 BIT_MASK(SND_TONE);
398 data->idev->event = pca9532_event; 398 data->idev->event = pca9532_event;
399 input_set_drvdata(data->idev, data); 399 input_set_drvdata(data->idev, data);
400 INIT_WORK(&data->work, pca9532_input_work); 400 INIT_WORK(&data->work, pca9532_input_work);
401 err = input_register_device(data->idev); 401 err = input_register_device(data->idev);
402 if (err) { 402 if (err) {
403 cancel_work_sync(&data->work); 403 cancel_work_sync(&data->work);
404 data->idev = NULL; 404 data->idev = NULL;
405 goto exit; 405 goto exit;
406 } 406 }
407 break; 407 break;
408 } 408 }
409 } 409 }
410 410
411 #ifdef CONFIG_LEDS_PCA9532_GPIO 411 #ifdef CONFIG_LEDS_PCA9532_GPIO
412 if (gpios) { 412 if (gpios) {
413 data->gpio.label = "gpio-pca9532"; 413 data->gpio.label = "gpio-pca9532";
414 data->gpio.direction_input = pca9532_gpio_direction_input; 414 data->gpio.direction_input = pca9532_gpio_direction_input;
415 data->gpio.direction_output = pca9532_gpio_direction_output; 415 data->gpio.direction_output = pca9532_gpio_direction_output;
416 data->gpio.set = pca9532_gpio_set_value; 416 data->gpio.set = pca9532_gpio_set_value;
417 data->gpio.get = pca9532_gpio_get_value; 417 data->gpio.get = pca9532_gpio_get_value;
418 data->gpio.request = pca9532_gpio_request_pin; 418 data->gpio.request = pca9532_gpio_request_pin;
419 data->gpio.can_sleep = 1; 419 data->gpio.can_sleep = 1;
420 data->gpio.base = pdata->gpio_base; 420 data->gpio.base = pdata->gpio_base;
421 data->gpio.ngpio = data->chip_info->num_leds; 421 data->gpio.ngpio = data->chip_info->num_leds;
422 data->gpio.dev = &client->dev; 422 data->gpio.dev = &client->dev;
423 data->gpio.owner = THIS_MODULE; 423 data->gpio.owner = THIS_MODULE;
424 424
425 err = gpiochip_add(&data->gpio); 425 err = gpiochip_add(&data->gpio);
426 if (err) { 426 if (err) {
427 /* Use data->gpio.dev as a flag for freeing gpiochip */ 427 /* Use data->gpio.dev as a flag for freeing gpiochip */
428 data->gpio.dev = NULL; 428 data->gpio.dev = NULL;
429 dev_warn(&client->dev, "could not add gpiochip\n"); 429 dev_warn(&client->dev, "could not add gpiochip\n");
430 } else { 430 } else {
431 dev_info(&client->dev, "gpios %i...%i\n", 431 dev_info(&client->dev, "gpios %i...%i\n",
432 data->gpio.base, data->gpio.base + 432 data->gpio.base, data->gpio.base +
433 data->gpio.ngpio - 1); 433 data->gpio.ngpio - 1);
434 } 434 }
435 } 435 }
436 #endif 436 #endif
437 437
438 return 0; 438 return 0;
439 439
440 exit: 440 exit:
441 pca9532_destroy_devices(data, i); 441 pca9532_destroy_devices(data, i);
442 return err; 442 return err;
443 } 443 }
444 444
445 static int pca9532_probe(struct i2c_client *client, 445 static int pca9532_probe(struct i2c_client *client,
446 const struct i2c_device_id *id) 446 const struct i2c_device_id *id)
447 { 447 {
448 struct pca9532_data *data = i2c_get_clientdata(client); 448 struct pca9532_data *data = i2c_get_clientdata(client);
449 struct pca9532_platform_data *pca9532_pdata = client->dev.platform_data; 449 struct pca9532_platform_data *pca9532_pdata =
450 dev_get_platdata(&client->dev);
450 451
451 if (!pca9532_pdata) 452 if (!pca9532_pdata)
452 return -EIO; 453 return -EIO;
453 454
454 if (!i2c_check_functionality(client->adapter, 455 if (!i2c_check_functionality(client->adapter,
455 I2C_FUNC_SMBUS_BYTE_DATA)) 456 I2C_FUNC_SMBUS_BYTE_DATA))
456 return -EIO; 457 return -EIO;
457 458
458 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); 459 data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
459 if (!data) 460 if (!data)
460 return -ENOMEM; 461 return -ENOMEM;
461 462
462 data->chip_info = &pca9532_chip_info_tbl[id->driver_data]; 463 data->chip_info = &pca9532_chip_info_tbl[id->driver_data];
463 464
464 dev_info(&client->dev, "setting platform data\n"); 465 dev_info(&client->dev, "setting platform data\n");
465 i2c_set_clientdata(client, data); 466 i2c_set_clientdata(client, data);
466 data->client = client; 467 data->client = client;
467 mutex_init(&data->update_lock); 468 mutex_init(&data->update_lock);
468 469
469 return pca9532_configure(client, data, pca9532_pdata); 470 return pca9532_configure(client, data, pca9532_pdata);
470 } 471 }
471 472
472 static int pca9532_remove(struct i2c_client *client) 473 static int pca9532_remove(struct i2c_client *client)
473 { 474 {
474 struct pca9532_data *data = i2c_get_clientdata(client); 475 struct pca9532_data *data = i2c_get_clientdata(client);
475 int err; 476 int err;
476 477
477 err = pca9532_destroy_devices(data, data->chip_info->num_leds); 478 err = pca9532_destroy_devices(data, data->chip_info->num_leds);
478 if (err) 479 if (err)
479 return err; 480 return err;
480 481
481 return 0; 482 return 0;
482 } 483 }
483 484
484 module_i2c_driver(pca9532_driver); 485 module_i2c_driver(pca9532_driver);
485 486
486 MODULE_AUTHOR("Riku Voipio"); 487 MODULE_AUTHOR("Riku Voipio");
487 MODULE_LICENSE("GPL"); 488 MODULE_LICENSE("GPL");
488 MODULE_DESCRIPTION("PCA 9532 LED dimmer"); 489 MODULE_DESCRIPTION("PCA 9532 LED dimmer");
489 490
drivers/leds/leds-pca955x.c
1 /* 1 /*
2 * Copyright 2007-2008 Extreme Engineering Solutions, Inc. 2 * Copyright 2007-2008 Extreme Engineering Solutions, Inc.
3 * 3 *
4 * Author: Nate Case <ncase@xes-inc.com> 4 * Author: Nate Case <ncase@xes-inc.com>
5 * 5 *
6 * This file is subject to the terms and conditions of version 2 of 6 * This file is subject to the terms and conditions of version 2 of
7 * the GNU General Public License. See the file COPYING in the main 7 * the GNU General Public License. See the file COPYING in the main
8 * directory of this archive for more details. 8 * directory of this archive for more details.
9 * 9 *
10 * LED driver for various PCA955x I2C LED drivers 10 * LED driver for various PCA955x I2C LED drivers
11 * 11 *
12 * Supported devices: 12 * Supported devices:
13 * 13 *
14 * Device Description 7-bit slave address 14 * Device Description 7-bit slave address
15 * ------ ----------- ------------------- 15 * ------ ----------- -------------------
16 * PCA9550 2-bit driver 0x60 .. 0x61 16 * PCA9550 2-bit driver 0x60 .. 0x61
17 * PCA9551 8-bit driver 0x60 .. 0x67 17 * PCA9551 8-bit driver 0x60 .. 0x67
18 * PCA9552 16-bit driver 0x60 .. 0x67 18 * PCA9552 16-bit driver 0x60 .. 0x67
19 * PCA9553/01 4-bit driver 0x62 19 * PCA9553/01 4-bit driver 0x62
20 * PCA9553/02 4-bit driver 0x63 20 * PCA9553/02 4-bit driver 0x63
21 * 21 *
22 * Philips PCA955x LED driver chips follow a register map as shown below: 22 * Philips PCA955x LED driver chips follow a register map as shown below:
23 * 23 *
24 * Control Register Description 24 * Control Register Description
25 * ---------------- ----------- 25 * ---------------- -----------
26 * 0x0 Input register 0 26 * 0x0 Input register 0
27 * .. 27 * ..
28 * NUM_INPUT_REGS - 1 Last Input register X 28 * NUM_INPUT_REGS - 1 Last Input register X
29 * 29 *
30 * NUM_INPUT_REGS Frequency prescaler 0 30 * NUM_INPUT_REGS Frequency prescaler 0
31 * NUM_INPUT_REGS + 1 PWM register 0 31 * NUM_INPUT_REGS + 1 PWM register 0
32 * NUM_INPUT_REGS + 2 Frequency prescaler 1 32 * NUM_INPUT_REGS + 2 Frequency prescaler 1
33 * NUM_INPUT_REGS + 3 PWM register 1 33 * NUM_INPUT_REGS + 3 PWM register 1
34 * 34 *
35 * NUM_INPUT_REGS + 4 LED selector 0 35 * NUM_INPUT_REGS + 4 LED selector 0
36 * NUM_INPUT_REGS + 4 36 * NUM_INPUT_REGS + 4
37 * + NUM_LED_REGS - 1 Last LED selector 37 * + NUM_LED_REGS - 1 Last LED selector
38 * 38 *
39 * where NUM_INPUT_REGS and NUM_LED_REGS vary depending on how many 39 * where NUM_INPUT_REGS and NUM_LED_REGS vary depending on how many
40 * bits the chip supports. 40 * bits the chip supports.
41 */ 41 */
42 42
43 #include <linux/module.h> 43 #include <linux/module.h>
44 #include <linux/delay.h> 44 #include <linux/delay.h>
45 #include <linux/string.h> 45 #include <linux/string.h>
46 #include <linux/ctype.h> 46 #include <linux/ctype.h>
47 #include <linux/leds.h> 47 #include <linux/leds.h>
48 #include <linux/err.h> 48 #include <linux/err.h>
49 #include <linux/i2c.h> 49 #include <linux/i2c.h>
50 #include <linux/workqueue.h> 50 #include <linux/workqueue.h>
51 #include <linux/slab.h> 51 #include <linux/slab.h>
52 52
53 /* LED select registers determine the source that drives LED outputs */ 53 /* LED select registers determine the source that drives LED outputs */
54 #define PCA955X_LS_LED_ON 0x0 /* Output LOW */ 54 #define PCA955X_LS_LED_ON 0x0 /* Output LOW */
55 #define PCA955X_LS_LED_OFF 0x1 /* Output HI-Z */ 55 #define PCA955X_LS_LED_OFF 0x1 /* Output HI-Z */
56 #define PCA955X_LS_BLINK0 0x2 /* Blink at PWM0 rate */ 56 #define PCA955X_LS_BLINK0 0x2 /* Blink at PWM0 rate */
57 #define PCA955X_LS_BLINK1 0x3 /* Blink at PWM1 rate */ 57 #define PCA955X_LS_BLINK1 0x3 /* Blink at PWM1 rate */
58 58
59 enum pca955x_type { 59 enum pca955x_type {
60 pca9550, 60 pca9550,
61 pca9551, 61 pca9551,
62 pca9552, 62 pca9552,
63 pca9553, 63 pca9553,
64 }; 64 };
65 65
66 struct pca955x_chipdef { 66 struct pca955x_chipdef {
67 int bits; 67 int bits;
68 u8 slv_addr; /* 7-bit slave address mask */ 68 u8 slv_addr; /* 7-bit slave address mask */
69 int slv_addr_shift; /* Number of bits to ignore */ 69 int slv_addr_shift; /* Number of bits to ignore */
70 }; 70 };
71 71
72 static struct pca955x_chipdef pca955x_chipdefs[] = { 72 static struct pca955x_chipdef pca955x_chipdefs[] = {
73 [pca9550] = { 73 [pca9550] = {
74 .bits = 2, 74 .bits = 2,
75 .slv_addr = /* 110000x */ 0x60, 75 .slv_addr = /* 110000x */ 0x60,
76 .slv_addr_shift = 1, 76 .slv_addr_shift = 1,
77 }, 77 },
78 [pca9551] = { 78 [pca9551] = {
79 .bits = 8, 79 .bits = 8,
80 .slv_addr = /* 1100xxx */ 0x60, 80 .slv_addr = /* 1100xxx */ 0x60,
81 .slv_addr_shift = 3, 81 .slv_addr_shift = 3,
82 }, 82 },
83 [pca9552] = { 83 [pca9552] = {
84 .bits = 16, 84 .bits = 16,
85 .slv_addr = /* 1100xxx */ 0x60, 85 .slv_addr = /* 1100xxx */ 0x60,
86 .slv_addr_shift = 3, 86 .slv_addr_shift = 3,
87 }, 87 },
88 [pca9553] = { 88 [pca9553] = {
89 .bits = 4, 89 .bits = 4,
90 .slv_addr = /* 110001x */ 0x62, 90 .slv_addr = /* 110001x */ 0x62,
91 .slv_addr_shift = 1, 91 .slv_addr_shift = 1,
92 }, 92 },
93 }; 93 };
94 94
95 static const struct i2c_device_id pca955x_id[] = { 95 static const struct i2c_device_id pca955x_id[] = {
96 { "pca9550", pca9550 }, 96 { "pca9550", pca9550 },
97 { "pca9551", pca9551 }, 97 { "pca9551", pca9551 },
98 { "pca9552", pca9552 }, 98 { "pca9552", pca9552 },
99 { "pca9553", pca9553 }, 99 { "pca9553", pca9553 },
100 { } 100 { }
101 }; 101 };
102 MODULE_DEVICE_TABLE(i2c, pca955x_id); 102 MODULE_DEVICE_TABLE(i2c, pca955x_id);
103 103
104 struct pca955x { 104 struct pca955x {
105 struct mutex lock; 105 struct mutex lock;
106 struct pca955x_led *leds; 106 struct pca955x_led *leds;
107 struct pca955x_chipdef *chipdef; 107 struct pca955x_chipdef *chipdef;
108 struct i2c_client *client; 108 struct i2c_client *client;
109 }; 109 };
110 110
111 struct pca955x_led { 111 struct pca955x_led {
112 struct pca955x *pca955x; 112 struct pca955x *pca955x;
113 struct work_struct work; 113 struct work_struct work;
114 enum led_brightness brightness; 114 enum led_brightness brightness;
115 struct led_classdev led_cdev; 115 struct led_classdev led_cdev;
116 int led_num; /* 0 .. 15 potentially */ 116 int led_num; /* 0 .. 15 potentially */
117 char name[32]; 117 char name[32];
118 }; 118 };
119 119
120 /* 8 bits per input register */ 120 /* 8 bits per input register */
121 static inline int pca95xx_num_input_regs(int bits) 121 static inline int pca95xx_num_input_regs(int bits)
122 { 122 {
123 return (bits + 7) / 8; 123 return (bits + 7) / 8;
124 } 124 }
125 125
126 /* 4 bits per LED selector register */ 126 /* 4 bits per LED selector register */
127 static inline int pca95xx_num_led_regs(int bits) 127 static inline int pca95xx_num_led_regs(int bits)
128 { 128 {
129 return (bits + 3) / 4; 129 return (bits + 3) / 4;
130 } 130 }
131 131
132 /* 132 /*
133 * Return an LED selector register value based on an existing one, with 133 * Return an LED selector register value based on an existing one, with
134 * the appropriate 2-bit state value set for the given LED number (0-3). 134 * the appropriate 2-bit state value set for the given LED number (0-3).
135 */ 135 */
136 static inline u8 pca955x_ledsel(u8 oldval, int led_num, int state) 136 static inline u8 pca955x_ledsel(u8 oldval, int led_num, int state)
137 { 137 {
138 return (oldval & (~(0x3 << (led_num << 1)))) | 138 return (oldval & (~(0x3 << (led_num << 1)))) |
139 ((state & 0x3) << (led_num << 1)); 139 ((state & 0x3) << (led_num << 1));
140 } 140 }
141 141
142 /* 142 /*
143 * Write to frequency prescaler register, used to program the 143 * Write to frequency prescaler register, used to program the
144 * period of the PWM output. period = (PSCx + 1) / 38 144 * period of the PWM output. period = (PSCx + 1) / 38
145 */ 145 */
146 static void pca955x_write_psc(struct i2c_client *client, int n, u8 val) 146 static void pca955x_write_psc(struct i2c_client *client, int n, u8 val)
147 { 147 {
148 struct pca955x *pca955x = i2c_get_clientdata(client); 148 struct pca955x *pca955x = i2c_get_clientdata(client);
149 149
150 i2c_smbus_write_byte_data(client, 150 i2c_smbus_write_byte_data(client,
151 pca95xx_num_input_regs(pca955x->chipdef->bits) + 2*n, 151 pca95xx_num_input_regs(pca955x->chipdef->bits) + 2*n,
152 val); 152 val);
153 } 153 }
154 154
155 /* 155 /*
156 * Write to PWM register, which determines the duty cycle of the 156 * Write to PWM register, which determines the duty cycle of the
157 * output. LED is OFF when the count is less than the value of this 157 * output. LED is OFF when the count is less than the value of this
158 * register, and ON when it is greater. If PWMx == 0, LED is always OFF. 158 * register, and ON when it is greater. If PWMx == 0, LED is always OFF.
159 * 159 *
160 * Duty cycle is (256 - PWMx) / 256 160 * Duty cycle is (256 - PWMx) / 256
161 */ 161 */
162 static void pca955x_write_pwm(struct i2c_client *client, int n, u8 val) 162 static void pca955x_write_pwm(struct i2c_client *client, int n, u8 val)
163 { 163 {
164 struct pca955x *pca955x = i2c_get_clientdata(client); 164 struct pca955x *pca955x = i2c_get_clientdata(client);
165 165
166 i2c_smbus_write_byte_data(client, 166 i2c_smbus_write_byte_data(client,
167 pca95xx_num_input_regs(pca955x->chipdef->bits) + 1 + 2*n, 167 pca95xx_num_input_regs(pca955x->chipdef->bits) + 1 + 2*n,
168 val); 168 val);
169 } 169 }
170 170
171 /* 171 /*
172 * Write to LED selector register, which determines the source that 172 * Write to LED selector register, which determines the source that
173 * drives the LED output. 173 * drives the LED output.
174 */ 174 */
175 static void pca955x_write_ls(struct i2c_client *client, int n, u8 val) 175 static void pca955x_write_ls(struct i2c_client *client, int n, u8 val)
176 { 176 {
177 struct pca955x *pca955x = i2c_get_clientdata(client); 177 struct pca955x *pca955x = i2c_get_clientdata(client);
178 178
179 i2c_smbus_write_byte_data(client, 179 i2c_smbus_write_byte_data(client,
180 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n, 180 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n,
181 val); 181 val);
182 } 182 }
183 183
184 /* 184 /*
185 * Read the LED selector register, which determines the source that 185 * Read the LED selector register, which determines the source that
186 * drives the LED output. 186 * drives the LED output.
187 */ 187 */
188 static u8 pca955x_read_ls(struct i2c_client *client, int n) 188 static u8 pca955x_read_ls(struct i2c_client *client, int n)
189 { 189 {
190 struct pca955x *pca955x = i2c_get_clientdata(client); 190 struct pca955x *pca955x = i2c_get_clientdata(client);
191 191
192 return (u8) i2c_smbus_read_byte_data(client, 192 return (u8) i2c_smbus_read_byte_data(client,
193 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n); 193 pca95xx_num_input_regs(pca955x->chipdef->bits) + 4 + n);
194 } 194 }
195 195
196 static void pca955x_led_work(struct work_struct *work) 196 static void pca955x_led_work(struct work_struct *work)
197 { 197 {
198 struct pca955x_led *pca955x_led; 198 struct pca955x_led *pca955x_led;
199 struct pca955x *pca955x; 199 struct pca955x *pca955x;
200 u8 ls; 200 u8 ls;
201 int chip_ls; /* which LSx to use (0-3 potentially) */ 201 int chip_ls; /* which LSx to use (0-3 potentially) */
202 int ls_led; /* which set of bits within LSx to use (0-3) */ 202 int ls_led; /* which set of bits within LSx to use (0-3) */
203 203
204 pca955x_led = container_of(work, struct pca955x_led, work); 204 pca955x_led = container_of(work, struct pca955x_led, work);
205 pca955x = pca955x_led->pca955x; 205 pca955x = pca955x_led->pca955x;
206 206
207 chip_ls = pca955x_led->led_num / 4; 207 chip_ls = pca955x_led->led_num / 4;
208 ls_led = pca955x_led->led_num % 4; 208 ls_led = pca955x_led->led_num % 4;
209 209
210 mutex_lock(&pca955x->lock); 210 mutex_lock(&pca955x->lock);
211 211
212 ls = pca955x_read_ls(pca955x->client, chip_ls); 212 ls = pca955x_read_ls(pca955x->client, chip_ls);
213 213
214 switch (pca955x_led->brightness) { 214 switch (pca955x_led->brightness) {
215 case LED_FULL: 215 case LED_FULL:
216 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON); 216 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_ON);
217 break; 217 break;
218 case LED_OFF: 218 case LED_OFF:
219 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_OFF); 219 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_LED_OFF);
220 break; 220 break;
221 case LED_HALF: 221 case LED_HALF:
222 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK0); 222 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK0);
223 break; 223 break;
224 default: 224 default:
225 /* 225 /*
226 * Use PWM1 for all other values. This has the unwanted 226 * Use PWM1 for all other values. This has the unwanted
227 * side effect of making all LEDs on the chip share the 227 * side effect of making all LEDs on the chip share the
228 * same brightness level if set to a value other than 228 * same brightness level if set to a value other than
229 * OFF, HALF, or FULL. But, this is probably better than 229 * OFF, HALF, or FULL. But, this is probably better than
230 * just turning off for all other values. 230 * just turning off for all other values.
231 */ 231 */
232 pca955x_write_pwm(pca955x->client, 1, 232 pca955x_write_pwm(pca955x->client, 1,
233 255 - pca955x_led->brightness); 233 255 - pca955x_led->brightness);
234 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK1); 234 ls = pca955x_ledsel(ls, ls_led, PCA955X_LS_BLINK1);
235 break; 235 break;
236 } 236 }
237 237
238 pca955x_write_ls(pca955x->client, chip_ls, ls); 238 pca955x_write_ls(pca955x->client, chip_ls, ls);
239 239
240 mutex_unlock(&pca955x->lock); 240 mutex_unlock(&pca955x->lock);
241 } 241 }
242 242
243 static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value) 243 static void pca955x_led_set(struct led_classdev *led_cdev, enum led_brightness value)
244 { 244 {
245 struct pca955x_led *pca955x; 245 struct pca955x_led *pca955x;
246 246
247 pca955x = container_of(led_cdev, struct pca955x_led, led_cdev); 247 pca955x = container_of(led_cdev, struct pca955x_led, led_cdev);
248 248
249 pca955x->brightness = value; 249 pca955x->brightness = value;
250 250
251 /* 251 /*
252 * Must use workqueue for the actual I/O since I2C operations 252 * Must use workqueue for the actual I/O since I2C operations
253 * can sleep. 253 * can sleep.
254 */ 254 */
255 schedule_work(&pca955x->work); 255 schedule_work(&pca955x->work);
256 } 256 }
257 257
258 static int pca955x_probe(struct i2c_client *client, 258 static int pca955x_probe(struct i2c_client *client,
259 const struct i2c_device_id *id) 259 const struct i2c_device_id *id)
260 { 260 {
261 struct pca955x *pca955x; 261 struct pca955x *pca955x;
262 struct pca955x_led *pca955x_led; 262 struct pca955x_led *pca955x_led;
263 struct pca955x_chipdef *chip; 263 struct pca955x_chipdef *chip;
264 struct i2c_adapter *adapter; 264 struct i2c_adapter *adapter;
265 struct led_platform_data *pdata; 265 struct led_platform_data *pdata;
266 int i, err; 266 int i, err;
267 267
268 chip = &pca955x_chipdefs[id->driver_data]; 268 chip = &pca955x_chipdefs[id->driver_data];
269 adapter = to_i2c_adapter(client->dev.parent); 269 adapter = to_i2c_adapter(client->dev.parent);
270 pdata = client->dev.platform_data; 270 pdata = dev_get_platdata(&client->dev);
271 271
272 /* Make sure the slave address / chip type combo given is possible */ 272 /* Make sure the slave address / chip type combo given is possible */
273 if ((client->addr & ~((1 << chip->slv_addr_shift) - 1)) != 273 if ((client->addr & ~((1 << chip->slv_addr_shift) - 1)) !=
274 chip->slv_addr) { 274 chip->slv_addr) {
275 dev_err(&client->dev, "invalid slave address %02x\n", 275 dev_err(&client->dev, "invalid slave address %02x\n",
276 client->addr); 276 client->addr);
277 return -ENODEV; 277 return -ENODEV;
278 } 278 }
279 279
280 dev_info(&client->dev, "leds-pca955x: Using %s %d-bit LED driver at " 280 dev_info(&client->dev, "leds-pca955x: Using %s %d-bit LED driver at "
281 "slave address 0x%02x\n", 281 "slave address 0x%02x\n",
282 id->name, chip->bits, client->addr); 282 id->name, chip->bits, client->addr);
283 283
284 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) 284 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
285 return -EIO; 285 return -EIO;
286 286
287 if (pdata) { 287 if (pdata) {
288 if (pdata->num_leds != chip->bits) { 288 if (pdata->num_leds != chip->bits) {
289 dev_err(&client->dev, "board info claims %d LEDs" 289 dev_err(&client->dev, "board info claims %d LEDs"
290 " on a %d-bit chip\n", 290 " on a %d-bit chip\n",
291 pdata->num_leds, chip->bits); 291 pdata->num_leds, chip->bits);
292 return -ENODEV; 292 return -ENODEV;
293 } 293 }
294 } 294 }
295 295
296 pca955x = devm_kzalloc(&client->dev, sizeof(*pca955x), GFP_KERNEL); 296 pca955x = devm_kzalloc(&client->dev, sizeof(*pca955x), GFP_KERNEL);
297 if (!pca955x) 297 if (!pca955x)
298 return -ENOMEM; 298 return -ENOMEM;
299 299
300 pca955x->leds = devm_kzalloc(&client->dev, 300 pca955x->leds = devm_kzalloc(&client->dev,
301 sizeof(*pca955x_led) * chip->bits, GFP_KERNEL); 301 sizeof(*pca955x_led) * chip->bits, GFP_KERNEL);
302 if (!pca955x->leds) 302 if (!pca955x->leds)
303 return -ENOMEM; 303 return -ENOMEM;
304 304
305 i2c_set_clientdata(client, pca955x); 305 i2c_set_clientdata(client, pca955x);
306 306
307 mutex_init(&pca955x->lock); 307 mutex_init(&pca955x->lock);
308 pca955x->client = client; 308 pca955x->client = client;
309 pca955x->chipdef = chip; 309 pca955x->chipdef = chip;
310 310
311 for (i = 0; i < chip->bits; i++) { 311 for (i = 0; i < chip->bits; i++) {
312 pca955x_led = &pca955x->leds[i]; 312 pca955x_led = &pca955x->leds[i];
313 pca955x_led->led_num = i; 313 pca955x_led->led_num = i;
314 pca955x_led->pca955x = pca955x; 314 pca955x_led->pca955x = pca955x;
315 315
316 /* Platform data can specify LED names and default triggers */ 316 /* Platform data can specify LED names and default triggers */
317 if (pdata) { 317 if (pdata) {
318 if (pdata->leds[i].name) 318 if (pdata->leds[i].name)
319 snprintf(pca955x_led->name, 319 snprintf(pca955x_led->name,
320 sizeof(pca955x_led->name), "pca955x:%s", 320 sizeof(pca955x_led->name), "pca955x:%s",
321 pdata->leds[i].name); 321 pdata->leds[i].name);
322 if (pdata->leds[i].default_trigger) 322 if (pdata->leds[i].default_trigger)
323 pca955x_led->led_cdev.default_trigger = 323 pca955x_led->led_cdev.default_trigger =
324 pdata->leds[i].default_trigger; 324 pdata->leds[i].default_trigger;
325 } else { 325 } else {
326 snprintf(pca955x_led->name, sizeof(pca955x_led->name), 326 snprintf(pca955x_led->name, sizeof(pca955x_led->name),
327 "pca955x:%d", i); 327 "pca955x:%d", i);
328 } 328 }
329 329
330 pca955x_led->led_cdev.name = pca955x_led->name; 330 pca955x_led->led_cdev.name = pca955x_led->name;
331 pca955x_led->led_cdev.brightness_set = pca955x_led_set; 331 pca955x_led->led_cdev.brightness_set = pca955x_led_set;
332 332
333 INIT_WORK(&pca955x_led->work, pca955x_led_work); 333 INIT_WORK(&pca955x_led->work, pca955x_led_work);
334 334
335 err = led_classdev_register(&client->dev, 335 err = led_classdev_register(&client->dev,
336 &pca955x_led->led_cdev); 336 &pca955x_led->led_cdev);
337 if (err < 0) 337 if (err < 0)
338 goto exit; 338 goto exit;
339 } 339 }
340 340
341 /* Turn off LEDs */ 341 /* Turn off LEDs */
342 for (i = 0; i < pca95xx_num_led_regs(chip->bits); i++) 342 for (i = 0; i < pca95xx_num_led_regs(chip->bits); i++)
343 pca955x_write_ls(client, i, 0x55); 343 pca955x_write_ls(client, i, 0x55);
344 344
345 /* PWM0 is used for half brightness or 50% duty cycle */ 345 /* PWM0 is used for half brightness or 50% duty cycle */
346 pca955x_write_pwm(client, 0, 255-LED_HALF); 346 pca955x_write_pwm(client, 0, 255-LED_HALF);
347 347
348 /* PWM1 is used for variable brightness, default to OFF */ 348 /* PWM1 is used for variable brightness, default to OFF */
349 pca955x_write_pwm(client, 1, 0); 349 pca955x_write_pwm(client, 1, 0);
350 350
351 /* Set to fast frequency so we do not see flashing */ 351 /* Set to fast frequency so we do not see flashing */
352 pca955x_write_psc(client, 0, 0); 352 pca955x_write_psc(client, 0, 0);
353 pca955x_write_psc(client, 1, 0); 353 pca955x_write_psc(client, 1, 0);
354 354
355 return 0; 355 return 0;
356 356
357 exit: 357 exit:
358 while (i--) { 358 while (i--) {
359 led_classdev_unregister(&pca955x->leds[i].led_cdev); 359 led_classdev_unregister(&pca955x->leds[i].led_cdev);
360 cancel_work_sync(&pca955x->leds[i].work); 360 cancel_work_sync(&pca955x->leds[i].work);
361 } 361 }
362 362
363 return err; 363 return err;
364 } 364 }
365 365
366 static int pca955x_remove(struct i2c_client *client) 366 static int pca955x_remove(struct i2c_client *client)
367 { 367 {
368 struct pca955x *pca955x = i2c_get_clientdata(client); 368 struct pca955x *pca955x = i2c_get_clientdata(client);
369 int i; 369 int i;
370 370
371 for (i = 0; i < pca955x->chipdef->bits; i++) { 371 for (i = 0; i < pca955x->chipdef->bits; i++) {
372 led_classdev_unregister(&pca955x->leds[i].led_cdev); 372 led_classdev_unregister(&pca955x->leds[i].led_cdev);
373 cancel_work_sync(&pca955x->leds[i].work); 373 cancel_work_sync(&pca955x->leds[i].work);
374 } 374 }
375 375
376 return 0; 376 return 0;
377 } 377 }
378 378
379 static struct i2c_driver pca955x_driver = { 379 static struct i2c_driver pca955x_driver = {
380 .driver = { 380 .driver = {
381 .name = "leds-pca955x", 381 .name = "leds-pca955x",
382 .owner = THIS_MODULE, 382 .owner = THIS_MODULE,
383 }, 383 },
384 .probe = pca955x_probe, 384 .probe = pca955x_probe,
385 .remove = pca955x_remove, 385 .remove = pca955x_remove,
386 .id_table = pca955x_id, 386 .id_table = pca955x_id,
387 }; 387 };
388 388
389 module_i2c_driver(pca955x_driver); 389 module_i2c_driver(pca955x_driver);
390 390
391 MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>"); 391 MODULE_AUTHOR("Nate Case <ncase@xes-inc.com>");
392 MODULE_DESCRIPTION("PCA955x LED driver"); 392 MODULE_DESCRIPTION("PCA955x LED driver");
393 MODULE_LICENSE("GPL v2"); 393 MODULE_LICENSE("GPL v2");
394 394
drivers/leds/leds-pca9633.c
1 /* 1 /*
2 * Copyright 2011 bct electronic GmbH 2 * Copyright 2011 bct electronic GmbH
3 * 3 *
4 * Author: Peter Meerwald <p.meerwald@bct-electronic.com> 4 * Author: Peter Meerwald <p.meerwald@bct-electronic.com>
5 * 5 *
6 * Based on leds-pca955x.c 6 * Based on leds-pca955x.c
7 * 7 *
8 * This file is subject to the terms and conditions of version 2 of 8 * This file is subject to the terms and conditions of version 2 of
9 * the GNU General Public License. See the file COPYING in the main 9 * the GNU General Public License. See the file COPYING in the main
10 * directory of this archive for more details. 10 * directory of this archive for more details.
11 * 11 *
12 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62) 12 * LED driver for the PCA9633 I2C LED driver (7-bit slave address 0x62)
13 * 13 *
14 * Note that hardware blinking violates the leds infrastructure driver 14 * Note that hardware blinking violates the leds infrastructure driver
15 * interface since the hardware only supports blinking all LEDs with the 15 * interface since the hardware only supports blinking all LEDs with the
16 * same delay_on/delay_off rates. That is, only the LEDs that are set to 16 * same delay_on/delay_off rates. That is, only the LEDs that are set to
17 * blink will actually blink but all LEDs that are set to blink will blink 17 * blink will actually blink but all LEDs that are set to blink will blink
18 * in identical fashion. The delay_on/delay_off values of the last LED 18 * in identical fashion. The delay_on/delay_off values of the last LED
19 * that is set to blink will be used for all of the blinking LEDs. 19 * that is set to blink will be used for all of the blinking LEDs.
20 * Hardware blinking is disabled by default but can be enabled by setting 20 * Hardware blinking is disabled by default but can be enabled by setting
21 * the 'blink_type' member in the platform_data struct to 'PCA9633_HW_BLINK' 21 * the 'blink_type' member in the platform_data struct to 'PCA9633_HW_BLINK'
22 * or by adding the 'nxp,hw-blink' property to the DTS. 22 * or by adding the 'nxp,hw-blink' property to the DTS.
23 */ 23 */
24 24
25 #include <linux/module.h> 25 #include <linux/module.h>
26 #include <linux/delay.h> 26 #include <linux/delay.h>
27 #include <linux/string.h> 27 #include <linux/string.h>
28 #include <linux/ctype.h> 28 #include <linux/ctype.h>
29 #include <linux/leds.h> 29 #include <linux/leds.h>
30 #include <linux/err.h> 30 #include <linux/err.h>
31 #include <linux/i2c.h> 31 #include <linux/i2c.h>
32 #include <linux/workqueue.h> 32 #include <linux/workqueue.h>
33 #include <linux/slab.h> 33 #include <linux/slab.h>
34 #include <linux/of.h> 34 #include <linux/of.h>
35 #include <linux/platform_data/leds-pca9633.h> 35 #include <linux/platform_data/leds-pca9633.h>
36 36
37 /* LED select registers determine the source that drives LED outputs */ 37 /* LED select registers determine the source that drives LED outputs */
38 #define PCA9633_LED_OFF 0x0 /* LED driver off */ 38 #define PCA9633_LED_OFF 0x0 /* LED driver off */
39 #define PCA9633_LED_ON 0x1 /* LED driver on */ 39 #define PCA9633_LED_ON 0x1 /* LED driver on */
40 #define PCA9633_LED_PWM 0x2 /* Controlled through PWM */ 40 #define PCA9633_LED_PWM 0x2 /* Controlled through PWM */
41 #define PCA9633_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */ 41 #define PCA9633_LED_GRP_PWM 0x3 /* Controlled through PWM/GRPPWM */
42 42
43 #define PCA9633_MODE2_DMBLNK 0x20 /* Enable blinking */ 43 #define PCA9633_MODE2_DMBLNK 0x20 /* Enable blinking */
44 44
45 #define PCA9633_MODE1 0x00 45 #define PCA9633_MODE1 0x00
46 #define PCA9633_MODE2 0x01 46 #define PCA9633_MODE2 0x01
47 #define PCA9633_PWM_BASE 0x02 47 #define PCA9633_PWM_BASE 0x02
48 #define PCA9633_GRPPWM 0x06 48 #define PCA9633_GRPPWM 0x06
49 #define PCA9633_GRPFREQ 0x07 49 #define PCA9633_GRPFREQ 0x07
50 #define PCA9633_LEDOUT 0x08 50 #define PCA9633_LEDOUT 0x08
51 51
52 /* Total blink period in milliseconds */ 52 /* Total blink period in milliseconds */
53 #define PCA9632_BLINK_PERIOD_MIN 42 53 #define PCA9632_BLINK_PERIOD_MIN 42
54 #define PCA9632_BLINK_PERIOD_MAX 10667 54 #define PCA9632_BLINK_PERIOD_MAX 10667
55 55
56 static const struct i2c_device_id pca9633_id[] = { 56 static const struct i2c_device_id pca9633_id[] = {
57 { "pca9633", 0 }, 57 { "pca9633", 0 },
58 { } 58 { }
59 }; 59 };
60 MODULE_DEVICE_TABLE(i2c, pca9633_id); 60 MODULE_DEVICE_TABLE(i2c, pca9633_id);
61 61
62 enum pca9633_cmd { 62 enum pca9633_cmd {
63 BRIGHTNESS_SET, 63 BRIGHTNESS_SET,
64 BLINK_SET, 64 BLINK_SET,
65 }; 65 };
66 66
67 struct pca9633_led { 67 struct pca9633_led {
68 struct i2c_client *client; 68 struct i2c_client *client;
69 struct work_struct work; 69 struct work_struct work;
70 enum led_brightness brightness; 70 enum led_brightness brightness;
71 struct led_classdev led_cdev; 71 struct led_classdev led_cdev;
72 int led_num; /* 0 .. 3 potentially */ 72 int led_num; /* 0 .. 3 potentially */
73 enum pca9633_cmd cmd; 73 enum pca9633_cmd cmd;
74 char name[32]; 74 char name[32];
75 u8 gdc; 75 u8 gdc;
76 u8 gfrq; 76 u8 gfrq;
77 }; 77 };
78 78
79 static void pca9633_brightness_work(struct pca9633_led *pca9633) 79 static void pca9633_brightness_work(struct pca9633_led *pca9633)
80 { 80 {
81 u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT); 81 u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
82 int shift = 2 * pca9633->led_num; 82 int shift = 2 * pca9633->led_num;
83 u8 mask = 0x3 << shift; 83 u8 mask = 0x3 << shift;
84 84
85 switch (pca9633->brightness) { 85 switch (pca9633->brightness) {
86 case LED_FULL: 86 case LED_FULL:
87 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT, 87 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
88 (ledout & ~mask) | (PCA9633_LED_ON << shift)); 88 (ledout & ~mask) | (PCA9633_LED_ON << shift));
89 break; 89 break;
90 case LED_OFF: 90 case LED_OFF:
91 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT, 91 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
92 ledout & ~mask); 92 ledout & ~mask);
93 break; 93 break;
94 default: 94 default:
95 i2c_smbus_write_byte_data(pca9633->client, 95 i2c_smbus_write_byte_data(pca9633->client,
96 PCA9633_PWM_BASE + pca9633->led_num, 96 PCA9633_PWM_BASE + pca9633->led_num,
97 pca9633->brightness); 97 pca9633->brightness);
98 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT, 98 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
99 (ledout & ~mask) | (PCA9633_LED_PWM << shift)); 99 (ledout & ~mask) | (PCA9633_LED_PWM << shift));
100 break; 100 break;
101 } 101 }
102 } 102 }
103 103
104 static void pca9633_blink_work(struct pca9633_led *pca9633) 104 static void pca9633_blink_work(struct pca9633_led *pca9633)
105 { 105 {
106 u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT); 106 u8 ledout = i2c_smbus_read_byte_data(pca9633->client, PCA9633_LEDOUT);
107 u8 mode2 = i2c_smbus_read_byte_data(pca9633->client, PCA9633_MODE2); 107 u8 mode2 = i2c_smbus_read_byte_data(pca9633->client, PCA9633_MODE2);
108 int shift = 2 * pca9633->led_num; 108 int shift = 2 * pca9633->led_num;
109 u8 mask = 0x3 << shift; 109 u8 mask = 0x3 << shift;
110 110
111 i2c_smbus_write_byte_data(pca9633->client, PCA9633_GRPPWM, 111 i2c_smbus_write_byte_data(pca9633->client, PCA9633_GRPPWM,
112 pca9633->gdc); 112 pca9633->gdc);
113 113
114 i2c_smbus_write_byte_data(pca9633->client, PCA9633_GRPFREQ, 114 i2c_smbus_write_byte_data(pca9633->client, PCA9633_GRPFREQ,
115 pca9633->gfrq); 115 pca9633->gfrq);
116 116
117 if (!(mode2 & PCA9633_MODE2_DMBLNK)) 117 if (!(mode2 & PCA9633_MODE2_DMBLNK))
118 i2c_smbus_write_byte_data(pca9633->client, PCA9633_MODE2, 118 i2c_smbus_write_byte_data(pca9633->client, PCA9633_MODE2,
119 mode2 | PCA9633_MODE2_DMBLNK); 119 mode2 | PCA9633_MODE2_DMBLNK);
120 120
121 if ((ledout & mask) != (PCA9633_LED_GRP_PWM << shift)) 121 if ((ledout & mask) != (PCA9633_LED_GRP_PWM << shift))
122 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT, 122 i2c_smbus_write_byte_data(pca9633->client, PCA9633_LEDOUT,
123 (ledout & ~mask) | (PCA9633_LED_GRP_PWM << shift)); 123 (ledout & ~mask) | (PCA9633_LED_GRP_PWM << shift));
124 } 124 }
125 125
126 static void pca9633_work(struct work_struct *work) 126 static void pca9633_work(struct work_struct *work)
127 { 127 {
128 struct pca9633_led *pca9633 = container_of(work, 128 struct pca9633_led *pca9633 = container_of(work,
129 struct pca9633_led, work); 129 struct pca9633_led, work);
130 130
131 switch (pca9633->cmd) { 131 switch (pca9633->cmd) {
132 case BRIGHTNESS_SET: 132 case BRIGHTNESS_SET:
133 pca9633_brightness_work(pca9633); 133 pca9633_brightness_work(pca9633);
134 break; 134 break;
135 case BLINK_SET: 135 case BLINK_SET:
136 pca9633_blink_work(pca9633); 136 pca9633_blink_work(pca9633);
137 break; 137 break;
138 } 138 }
139 } 139 }
140 140
141 static void pca9633_led_set(struct led_classdev *led_cdev, 141 static void pca9633_led_set(struct led_classdev *led_cdev,
142 enum led_brightness value) 142 enum led_brightness value)
143 { 143 {
144 struct pca9633_led *pca9633; 144 struct pca9633_led *pca9633;
145 145
146 pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev); 146 pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
147 147
148 pca9633->cmd = BRIGHTNESS_SET; 148 pca9633->cmd = BRIGHTNESS_SET;
149 pca9633->brightness = value; 149 pca9633->brightness = value;
150 150
151 /* 151 /*
152 * Must use workqueue for the actual I/O since I2C operations 152 * Must use workqueue for the actual I/O since I2C operations
153 * can sleep. 153 * can sleep.
154 */ 154 */
155 schedule_work(&pca9633->work); 155 schedule_work(&pca9633->work);
156 } 156 }
157 157
158 static int pca9633_blink_set(struct led_classdev *led_cdev, 158 static int pca9633_blink_set(struct led_classdev *led_cdev,
159 unsigned long *delay_on, unsigned long *delay_off) 159 unsigned long *delay_on, unsigned long *delay_off)
160 { 160 {
161 struct pca9633_led *pca9633; 161 struct pca9633_led *pca9633;
162 unsigned long time_on, time_off, period; 162 unsigned long time_on, time_off, period;
163 u8 gdc, gfrq; 163 u8 gdc, gfrq;
164 164
165 pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev); 165 pca9633 = container_of(led_cdev, struct pca9633_led, led_cdev);
166 166
167 time_on = *delay_on; 167 time_on = *delay_on;
168 time_off = *delay_off; 168 time_off = *delay_off;
169 169
170 /* If both zero, pick reasonable defaults of 500ms each */ 170 /* If both zero, pick reasonable defaults of 500ms each */
171 if (!time_on && !time_off) { 171 if (!time_on && !time_off) {
172 time_on = 500; 172 time_on = 500;
173 time_off = 500; 173 time_off = 500;
174 } 174 }
175 175
176 period = time_on + time_off; 176 period = time_on + time_off;
177 177
178 /* If period not supported by hardware, default to someting sane. */ 178 /* If period not supported by hardware, default to someting sane. */
179 if ((period < PCA9632_BLINK_PERIOD_MIN) || 179 if ((period < PCA9632_BLINK_PERIOD_MIN) ||
180 (period > PCA9632_BLINK_PERIOD_MAX)) { 180 (period > PCA9632_BLINK_PERIOD_MAX)) {
181 time_on = 500; 181 time_on = 500;
182 time_off = 500; 182 time_off = 500;
183 period = time_on + time_off; 183 period = time_on + time_off;
184 } 184 }
185 185
186 /* 186 /*
187 * From manual: duty cycle = (GDC / 256) -> 187 * From manual: duty cycle = (GDC / 256) ->
188 * (time_on / period) = (GDC / 256) -> 188 * (time_on / period) = (GDC / 256) ->
189 * GDC = ((time_on * 256) / period) 189 * GDC = ((time_on * 256) / period)
190 */ 190 */
191 gdc = (time_on * 256) / period; 191 gdc = (time_on * 256) / period;
192 192
193 /* 193 /*
194 * From manual: period = ((GFRQ + 1) / 24) in seconds. 194 * From manual: period = ((GFRQ + 1) / 24) in seconds.
195 * So, period (in ms) = (((GFRQ + 1) / 24) * 1000) -> 195 * So, period (in ms) = (((GFRQ + 1) / 24) * 1000) ->
196 * GFRQ = ((period * 24 / 1000) - 1) 196 * GFRQ = ((period * 24 / 1000) - 1)
197 */ 197 */
198 gfrq = (period * 24 / 1000) - 1; 198 gfrq = (period * 24 / 1000) - 1;
199 199
200 pca9633->cmd = BLINK_SET; 200 pca9633->cmd = BLINK_SET;
201 pca9633->gdc = gdc; 201 pca9633->gdc = gdc;
202 pca9633->gfrq = gfrq; 202 pca9633->gfrq = gfrq;
203 203
204 /* 204 /*
205 * Must use workqueue for the actual I/O since I2C operations 205 * Must use workqueue for the actual I/O since I2C operations
206 * can sleep. 206 * can sleep.
207 */ 207 */
208 schedule_work(&pca9633->work); 208 schedule_work(&pca9633->work);
209 209
210 *delay_on = time_on; 210 *delay_on = time_on;
211 *delay_off = time_off; 211 *delay_off = time_off;
212 212
213 return 0; 213 return 0;
214 } 214 }
215 215
216 #if IS_ENABLED(CONFIG_OF) 216 #if IS_ENABLED(CONFIG_OF)
217 static struct pca9633_platform_data * 217 static struct pca9633_platform_data *
218 pca9633_dt_init(struct i2c_client *client) 218 pca9633_dt_init(struct i2c_client *client)
219 { 219 {
220 struct device_node *np = client->dev.of_node, *child; 220 struct device_node *np = client->dev.of_node, *child;
221 struct pca9633_platform_data *pdata; 221 struct pca9633_platform_data *pdata;
222 struct led_info *pca9633_leds; 222 struct led_info *pca9633_leds;
223 int count; 223 int count;
224 224
225 count = of_get_child_count(np); 225 count = of_get_child_count(np);
226 if (!count || count > 4) 226 if (!count || count > 4)
227 return ERR_PTR(-ENODEV); 227 return ERR_PTR(-ENODEV);
228 228
229 pca9633_leds = devm_kzalloc(&client->dev, 229 pca9633_leds = devm_kzalloc(&client->dev,
230 sizeof(struct led_info) * count, GFP_KERNEL); 230 sizeof(struct led_info) * count, GFP_KERNEL);
231 if (!pca9633_leds) 231 if (!pca9633_leds)
232 return ERR_PTR(-ENOMEM); 232 return ERR_PTR(-ENOMEM);
233 233
234 for_each_child_of_node(np, child) { 234 for_each_child_of_node(np, child) {
235 struct led_info led; 235 struct led_info led;
236 u32 reg; 236 u32 reg;
237 int res; 237 int res;
238 238
239 led.name = 239 led.name =
240 of_get_property(child, "label", NULL) ? : child->name; 240 of_get_property(child, "label", NULL) ? : child->name;
241 led.default_trigger = 241 led.default_trigger =
242 of_get_property(child, "linux,default-trigger", NULL); 242 of_get_property(child, "linux,default-trigger", NULL);
243 res = of_property_read_u32(child, "reg", &reg); 243 res = of_property_read_u32(child, "reg", &reg);
244 if (res != 0) 244 if (res != 0)
245 continue; 245 continue;
246 pca9633_leds[reg] = led; 246 pca9633_leds[reg] = led;
247 } 247 }
248 pdata = devm_kzalloc(&client->dev, 248 pdata = devm_kzalloc(&client->dev,
249 sizeof(struct pca9633_platform_data), GFP_KERNEL); 249 sizeof(struct pca9633_platform_data), GFP_KERNEL);
250 if (!pdata) 250 if (!pdata)
251 return ERR_PTR(-ENOMEM); 251 return ERR_PTR(-ENOMEM);
252 252
253 pdata->leds.leds = pca9633_leds; 253 pdata->leds.leds = pca9633_leds;
254 pdata->leds.num_leds = count; 254 pdata->leds.num_leds = count;
255 255
256 /* default to open-drain unless totem pole (push-pull) is specified */ 256 /* default to open-drain unless totem pole (push-pull) is specified */
257 if (of_property_read_bool(np, "nxp,totem-pole")) 257 if (of_property_read_bool(np, "nxp,totem-pole"))
258 pdata->outdrv = PCA9633_TOTEM_POLE; 258 pdata->outdrv = PCA9633_TOTEM_POLE;
259 else 259 else
260 pdata->outdrv = PCA9633_OPEN_DRAIN; 260 pdata->outdrv = PCA9633_OPEN_DRAIN;
261 261
262 /* default to software blinking unless hardware blinking is specified */ 262 /* default to software blinking unless hardware blinking is specified */
263 if (of_property_read_bool(np, "nxp,hw-blink")) 263 if (of_property_read_bool(np, "nxp,hw-blink"))
264 pdata->blink_type = PCA9633_HW_BLINK; 264 pdata->blink_type = PCA9633_HW_BLINK;
265 else 265 else
266 pdata->blink_type = PCA9633_SW_BLINK; 266 pdata->blink_type = PCA9633_SW_BLINK;
267 267
268 return pdata; 268 return pdata;
269 } 269 }
270 270
271 static const struct of_device_id of_pca9633_match[] = { 271 static const struct of_device_id of_pca9633_match[] = {
272 { .compatible = "nxp,pca963x", }, 272 { .compatible = "nxp,pca963x", },
273 {}, 273 {},
274 }; 274 };
275 #else 275 #else
276 static struct pca9633_platform_data * 276 static struct pca9633_platform_data *
277 pca9633_dt_init(struct i2c_client *client) 277 pca9633_dt_init(struct i2c_client *client)
278 { 278 {
279 return ERR_PTR(-ENODEV); 279 return ERR_PTR(-ENODEV);
280 } 280 }
281 #endif 281 #endif
282 282
283 static int pca9633_probe(struct i2c_client *client, 283 static int pca9633_probe(struct i2c_client *client,
284 const struct i2c_device_id *id) 284 const struct i2c_device_id *id)
285 { 285 {
286 struct pca9633_led *pca9633; 286 struct pca9633_led *pca9633;
287 struct pca9633_platform_data *pdata; 287 struct pca9633_platform_data *pdata;
288 int i, err; 288 int i, err;
289 289
290 pdata = client->dev.platform_data; 290 pdata = dev_get_platdata(&client->dev);
291 291
292 if (!pdata) { 292 if (!pdata) {
293 pdata = pca9633_dt_init(client); 293 pdata = pca9633_dt_init(client);
294 if (IS_ERR(pdata)) { 294 if (IS_ERR(pdata)) {
295 dev_warn(&client->dev, "could not parse configuration\n"); 295 dev_warn(&client->dev, "could not parse configuration\n");
296 pdata = NULL; 296 pdata = NULL;
297 } 297 }
298 } 298 }
299 299
300 if (pdata) { 300 if (pdata) {
301 if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) { 301 if (pdata->leds.num_leds <= 0 || pdata->leds.num_leds > 4) {
302 dev_err(&client->dev, "board info must claim at most 4 LEDs"); 302 dev_err(&client->dev, "board info must claim at most 4 LEDs");
303 return -EINVAL; 303 return -EINVAL;
304 } 304 }
305 } 305 }
306 306
307 pca9633 = devm_kzalloc(&client->dev, 4 * sizeof(*pca9633), GFP_KERNEL); 307 pca9633 = devm_kzalloc(&client->dev, 4 * sizeof(*pca9633), GFP_KERNEL);
308 if (!pca9633) 308 if (!pca9633)
309 return -ENOMEM; 309 return -ENOMEM;
310 310
311 i2c_set_clientdata(client, pca9633); 311 i2c_set_clientdata(client, pca9633);
312 312
313 for (i = 0; i < 4; i++) { 313 for (i = 0; i < 4; i++) {
314 pca9633[i].client = client; 314 pca9633[i].client = client;
315 pca9633[i].led_num = i; 315 pca9633[i].led_num = i;
316 316
317 /* Platform data can specify LED names and default triggers */ 317 /* Platform data can specify LED names and default triggers */
318 if (pdata && i < pdata->leds.num_leds) { 318 if (pdata && i < pdata->leds.num_leds) {
319 if (pdata->leds.leds[i].name) 319 if (pdata->leds.leds[i].name)
320 snprintf(pca9633[i].name, 320 snprintf(pca9633[i].name,
321 sizeof(pca9633[i].name), "pca9633:%s", 321 sizeof(pca9633[i].name), "pca9633:%s",
322 pdata->leds.leds[i].name); 322 pdata->leds.leds[i].name);
323 if (pdata->leds.leds[i].default_trigger) 323 if (pdata->leds.leds[i].default_trigger)
324 pca9633[i].led_cdev.default_trigger = 324 pca9633[i].led_cdev.default_trigger =
325 pdata->leds.leds[i].default_trigger; 325 pdata->leds.leds[i].default_trigger;
326 } else { 326 } else {
327 snprintf(pca9633[i].name, sizeof(pca9633[i].name), 327 snprintf(pca9633[i].name, sizeof(pca9633[i].name),
328 "pca9633:%d", i); 328 "pca9633:%d", i);
329 } 329 }
330 330
331 pca9633[i].led_cdev.name = pca9633[i].name; 331 pca9633[i].led_cdev.name = pca9633[i].name;
332 pca9633[i].led_cdev.brightness_set = pca9633_led_set; 332 pca9633[i].led_cdev.brightness_set = pca9633_led_set;
333 333
334 if (pdata && pdata->blink_type == PCA9633_HW_BLINK) 334 if (pdata && pdata->blink_type == PCA9633_HW_BLINK)
335 pca9633[i].led_cdev.blink_set = pca9633_blink_set; 335 pca9633[i].led_cdev.blink_set = pca9633_blink_set;
336 336
337 INIT_WORK(&pca9633[i].work, pca9633_work); 337 INIT_WORK(&pca9633[i].work, pca9633_work);
338 338
339 err = led_classdev_register(&client->dev, &pca9633[i].led_cdev); 339 err = led_classdev_register(&client->dev, &pca9633[i].led_cdev);
340 if (err < 0) 340 if (err < 0)
341 goto exit; 341 goto exit;
342 } 342 }
343 343
344 /* Disable LED all-call address and set normal mode */ 344 /* Disable LED all-call address and set normal mode */
345 i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00); 345 i2c_smbus_write_byte_data(client, PCA9633_MODE1, 0x00);
346 346
347 /* Configure output: open-drain or totem pole (push-pull) */ 347 /* Configure output: open-drain or totem pole (push-pull) */
348 if (pdata && pdata->outdrv == PCA9633_OPEN_DRAIN) 348 if (pdata && pdata->outdrv == PCA9633_OPEN_DRAIN)
349 i2c_smbus_write_byte_data(client, PCA9633_MODE2, 0x01); 349 i2c_smbus_write_byte_data(client, PCA9633_MODE2, 0x01);
350 350
351 /* Turn off LEDs */ 351 /* Turn off LEDs */
352 i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00); 352 i2c_smbus_write_byte_data(client, PCA9633_LEDOUT, 0x00);
353 353
354 return 0; 354 return 0;
355 355
356 exit: 356 exit:
357 while (i--) { 357 while (i--) {
358 led_classdev_unregister(&pca9633[i].led_cdev); 358 led_classdev_unregister(&pca9633[i].led_cdev);
359 cancel_work_sync(&pca9633[i].work); 359 cancel_work_sync(&pca9633[i].work);
360 } 360 }
361 361
362 return err; 362 return err;
363 } 363 }
364 364
365 static int pca9633_remove(struct i2c_client *client) 365 static int pca9633_remove(struct i2c_client *client)
366 { 366 {
367 struct pca9633_led *pca9633 = i2c_get_clientdata(client); 367 struct pca9633_led *pca9633 = i2c_get_clientdata(client);
368 int i; 368 int i;
369 369
370 for (i = 0; i < 4; i++) { 370 for (i = 0; i < 4; i++) {
371 led_classdev_unregister(&pca9633[i].led_cdev); 371 led_classdev_unregister(&pca9633[i].led_cdev);
372 cancel_work_sync(&pca9633[i].work); 372 cancel_work_sync(&pca9633[i].work);
373 } 373 }
374 374
375 return 0; 375 return 0;
376 } 376 }
377 377
378 static struct i2c_driver pca9633_driver = { 378 static struct i2c_driver pca9633_driver = {
379 .driver = { 379 .driver = {
380 .name = "leds-pca9633", 380 .name = "leds-pca9633",
381 .owner = THIS_MODULE, 381 .owner = THIS_MODULE,
382 .of_match_table = of_match_ptr(of_pca9633_match), 382 .of_match_table = of_match_ptr(of_pca9633_match),
383 }, 383 },
384 .probe = pca9633_probe, 384 .probe = pca9633_probe,
385 .remove = pca9633_remove, 385 .remove = pca9633_remove,
386 .id_table = pca9633_id, 386 .id_table = pca9633_id,
387 }; 387 };
388 388
389 module_i2c_driver(pca9633_driver); 389 module_i2c_driver(pca9633_driver);
390 390
391 MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>"); 391 MODULE_AUTHOR("Peter Meerwald <p.meerwald@bct-electronic.com>");
392 MODULE_DESCRIPTION("PCA9633 LED driver"); 392 MODULE_DESCRIPTION("PCA9633 LED driver");
393 MODULE_LICENSE("GPL v2"); 393 MODULE_LICENSE("GPL v2");
394 394
drivers/leds/leds-pwm.c
1 /* 1 /*
2 * linux/drivers/leds-pwm.c 2 * linux/drivers/leds-pwm.c
3 * 3 *
4 * simple PWM based LED control 4 * simple PWM based LED control
5 * 5 *
6 * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de) 6 * Copyright 2009 Luotao Fu @ Pengutronix (l.fu@pengutronix.de)
7 * 7 *
8 * based on leds-gpio.c by Raphael Assenat <raph@8d.com> 8 * based on leds-gpio.c by Raphael Assenat <raph@8d.com>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15 #include <linux/module.h> 15 #include <linux/module.h>
16 #include <linux/kernel.h> 16 #include <linux/kernel.h>
17 #include <linux/init.h> 17 #include <linux/init.h>
18 #include <linux/platform_device.h> 18 #include <linux/platform_device.h>
19 #include <linux/of_platform.h> 19 #include <linux/of_platform.h>
20 #include <linux/fb.h> 20 #include <linux/fb.h>
21 #include <linux/leds.h> 21 #include <linux/leds.h>
22 #include <linux/err.h> 22 #include <linux/err.h>
23 #include <linux/pwm.h> 23 #include <linux/pwm.h>
24 #include <linux/leds_pwm.h> 24 #include <linux/leds_pwm.h>
25 #include <linux/slab.h> 25 #include <linux/slab.h>
26 #include <linux/workqueue.h> 26 #include <linux/workqueue.h>
27 27
28 struct led_pwm_data { 28 struct led_pwm_data {
29 struct led_classdev cdev; 29 struct led_classdev cdev;
30 struct pwm_device *pwm; 30 struct pwm_device *pwm;
31 struct work_struct work; 31 struct work_struct work;
32 unsigned int active_low; 32 unsigned int active_low;
33 unsigned int period; 33 unsigned int period;
34 int duty; 34 int duty;
35 bool can_sleep; 35 bool can_sleep;
36 }; 36 };
37 37
38 struct led_pwm_priv { 38 struct led_pwm_priv {
39 int num_leds; 39 int num_leds;
40 struct led_pwm_data leds[0]; 40 struct led_pwm_data leds[0];
41 }; 41 };
42 42
43 static void __led_pwm_set(struct led_pwm_data *led_dat) 43 static void __led_pwm_set(struct led_pwm_data *led_dat)
44 { 44 {
45 int new_duty = led_dat->duty; 45 int new_duty = led_dat->duty;
46 46
47 pwm_config(led_dat->pwm, new_duty, led_dat->period); 47 pwm_config(led_dat->pwm, new_duty, led_dat->period);
48 48
49 if (new_duty == 0) 49 if (new_duty == 0)
50 pwm_disable(led_dat->pwm); 50 pwm_disable(led_dat->pwm);
51 else 51 else
52 pwm_enable(led_dat->pwm); 52 pwm_enable(led_dat->pwm);
53 } 53 }
54 54
55 static void led_pwm_work(struct work_struct *work) 55 static void led_pwm_work(struct work_struct *work)
56 { 56 {
57 struct led_pwm_data *led_dat = 57 struct led_pwm_data *led_dat =
58 container_of(work, struct led_pwm_data, work); 58 container_of(work, struct led_pwm_data, work);
59 59
60 __led_pwm_set(led_dat); 60 __led_pwm_set(led_dat);
61 } 61 }
62 62
63 static void led_pwm_set(struct led_classdev *led_cdev, 63 static void led_pwm_set(struct led_classdev *led_cdev,
64 enum led_brightness brightness) 64 enum led_brightness brightness)
65 { 65 {
66 struct led_pwm_data *led_dat = 66 struct led_pwm_data *led_dat =
67 container_of(led_cdev, struct led_pwm_data, cdev); 67 container_of(led_cdev, struct led_pwm_data, cdev);
68 unsigned int max = led_dat->cdev.max_brightness; 68 unsigned int max = led_dat->cdev.max_brightness;
69 unsigned int period = led_dat->period; 69 unsigned int period = led_dat->period;
70 70
71 led_dat->duty = brightness * period / max; 71 led_dat->duty = brightness * period / max;
72 72
73 if (led_dat->can_sleep) 73 if (led_dat->can_sleep)
74 schedule_work(&led_dat->work); 74 schedule_work(&led_dat->work);
75 else 75 else
76 __led_pwm_set(led_dat); 76 __led_pwm_set(led_dat);
77 } 77 }
78 78
79 static inline size_t sizeof_pwm_leds_priv(int num_leds) 79 static inline size_t sizeof_pwm_leds_priv(int num_leds)
80 { 80 {
81 return sizeof(struct led_pwm_priv) + 81 return sizeof(struct led_pwm_priv) +
82 (sizeof(struct led_pwm_data) * num_leds); 82 (sizeof(struct led_pwm_data) * num_leds);
83 } 83 }
84 84
85 static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev) 85 static struct led_pwm_priv *led_pwm_create_of(struct platform_device *pdev)
86 { 86 {
87 struct device_node *node = pdev->dev.of_node; 87 struct device_node *node = pdev->dev.of_node;
88 struct device_node *child; 88 struct device_node *child;
89 struct led_pwm_priv *priv; 89 struct led_pwm_priv *priv;
90 int count, ret; 90 int count, ret;
91 91
92 /* count LEDs in this device, so we know how much to allocate */ 92 /* count LEDs in this device, so we know how much to allocate */
93 count = of_get_child_count(node); 93 count = of_get_child_count(node);
94 if (!count) 94 if (!count)
95 return NULL; 95 return NULL;
96 96
97 priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count), 97 priv = devm_kzalloc(&pdev->dev, sizeof_pwm_leds_priv(count),
98 GFP_KERNEL); 98 GFP_KERNEL);
99 if (!priv) 99 if (!priv)
100 return NULL; 100 return NULL;
101 101
102 for_each_child_of_node(node, child) { 102 for_each_child_of_node(node, child) {
103 struct led_pwm_data *led_dat = &priv->leds[priv->num_leds]; 103 struct led_pwm_data *led_dat = &priv->leds[priv->num_leds];
104 104
105 led_dat->cdev.name = of_get_property(child, "label", 105 led_dat->cdev.name = of_get_property(child, "label",
106 NULL) ? : child->name; 106 NULL) ? : child->name;
107 107
108 led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL); 108 led_dat->pwm = devm_of_pwm_get(&pdev->dev, child, NULL);
109 if (IS_ERR(led_dat->pwm)) { 109 if (IS_ERR(led_dat->pwm)) {
110 dev_err(&pdev->dev, "unable to request PWM for %s\n", 110 dev_err(&pdev->dev, "unable to request PWM for %s\n",
111 led_dat->cdev.name); 111 led_dat->cdev.name);
112 goto err; 112 goto err;
113 } 113 }
114 /* Get the period from PWM core when n*/ 114 /* Get the period from PWM core when n*/
115 led_dat->period = pwm_get_period(led_dat->pwm); 115 led_dat->period = pwm_get_period(led_dat->pwm);
116 116
117 led_dat->cdev.default_trigger = of_get_property(child, 117 led_dat->cdev.default_trigger = of_get_property(child,
118 "linux,default-trigger", NULL); 118 "linux,default-trigger", NULL);
119 of_property_read_u32(child, "max-brightness", 119 of_property_read_u32(child, "max-brightness",
120 &led_dat->cdev.max_brightness); 120 &led_dat->cdev.max_brightness);
121 121
122 led_dat->cdev.brightness_set = led_pwm_set; 122 led_dat->cdev.brightness_set = led_pwm_set;
123 led_dat->cdev.brightness = LED_OFF; 123 led_dat->cdev.brightness = LED_OFF;
124 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 124 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
125 125
126 led_dat->can_sleep = pwm_can_sleep(led_dat->pwm); 126 led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
127 if (led_dat->can_sleep) 127 if (led_dat->can_sleep)
128 INIT_WORK(&led_dat->work, led_pwm_work); 128 INIT_WORK(&led_dat->work, led_pwm_work);
129 129
130 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 130 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
131 if (ret < 0) { 131 if (ret < 0) {
132 dev_err(&pdev->dev, "failed to register for %s\n", 132 dev_err(&pdev->dev, "failed to register for %s\n",
133 led_dat->cdev.name); 133 led_dat->cdev.name);
134 of_node_put(child); 134 of_node_put(child);
135 goto err; 135 goto err;
136 } 136 }
137 priv->num_leds++; 137 priv->num_leds++;
138 } 138 }
139 139
140 return priv; 140 return priv;
141 err: 141 err:
142 while (priv->num_leds--) 142 while (priv->num_leds--)
143 led_classdev_unregister(&priv->leds[priv->num_leds].cdev); 143 led_classdev_unregister(&priv->leds[priv->num_leds].cdev);
144 144
145 return NULL; 145 return NULL;
146 } 146 }
147 147
148 static int led_pwm_probe(struct platform_device *pdev) 148 static int led_pwm_probe(struct platform_device *pdev)
149 { 149 {
150 struct led_pwm_platform_data *pdata = pdev->dev.platform_data; 150 struct led_pwm_platform_data *pdata = dev_get_platdata(&pdev->dev);
151 struct led_pwm_priv *priv; 151 struct led_pwm_priv *priv;
152 int i, ret = 0; 152 int i, ret = 0;
153 153
154 if (pdata && pdata->num_leds) { 154 if (pdata && pdata->num_leds) {
155 priv = devm_kzalloc(&pdev->dev, 155 priv = devm_kzalloc(&pdev->dev,
156 sizeof_pwm_leds_priv(pdata->num_leds), 156 sizeof_pwm_leds_priv(pdata->num_leds),
157 GFP_KERNEL); 157 GFP_KERNEL);
158 if (!priv) 158 if (!priv)
159 return -ENOMEM; 159 return -ENOMEM;
160 160
161 for (i = 0; i < pdata->num_leds; i++) { 161 for (i = 0; i < pdata->num_leds; i++) {
162 struct led_pwm *cur_led = &pdata->leds[i]; 162 struct led_pwm *cur_led = &pdata->leds[i];
163 struct led_pwm_data *led_dat = &priv->leds[i]; 163 struct led_pwm_data *led_dat = &priv->leds[i];
164 164
165 led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name); 165 led_dat->pwm = devm_pwm_get(&pdev->dev, cur_led->name);
166 if (IS_ERR(led_dat->pwm)) { 166 if (IS_ERR(led_dat->pwm)) {
167 ret = PTR_ERR(led_dat->pwm); 167 ret = PTR_ERR(led_dat->pwm);
168 dev_err(&pdev->dev, 168 dev_err(&pdev->dev,
169 "unable to request PWM for %s\n", 169 "unable to request PWM for %s\n",
170 cur_led->name); 170 cur_led->name);
171 goto err; 171 goto err;
172 } 172 }
173 173
174 led_dat->cdev.name = cur_led->name; 174 led_dat->cdev.name = cur_led->name;
175 led_dat->cdev.default_trigger = cur_led->default_trigger; 175 led_dat->cdev.default_trigger = cur_led->default_trigger;
176 led_dat->active_low = cur_led->active_low; 176 led_dat->active_low = cur_led->active_low;
177 led_dat->period = cur_led->pwm_period_ns; 177 led_dat->period = cur_led->pwm_period_ns;
178 led_dat->cdev.brightness_set = led_pwm_set; 178 led_dat->cdev.brightness_set = led_pwm_set;
179 led_dat->cdev.brightness = LED_OFF; 179 led_dat->cdev.brightness = LED_OFF;
180 led_dat->cdev.max_brightness = cur_led->max_brightness; 180 led_dat->cdev.max_brightness = cur_led->max_brightness;
181 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; 181 led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME;
182 182
183 led_dat->can_sleep = pwm_can_sleep(led_dat->pwm); 183 led_dat->can_sleep = pwm_can_sleep(led_dat->pwm);
184 if (led_dat->can_sleep) 184 if (led_dat->can_sleep)
185 INIT_WORK(&led_dat->work, led_pwm_work); 185 INIT_WORK(&led_dat->work, led_pwm_work);
186 186
187 ret = led_classdev_register(&pdev->dev, &led_dat->cdev); 187 ret = led_classdev_register(&pdev->dev, &led_dat->cdev);
188 if (ret < 0) 188 if (ret < 0)
189 goto err; 189 goto err;
190 } 190 }
191 priv->num_leds = pdata->num_leds; 191 priv->num_leds = pdata->num_leds;
192 } else { 192 } else {
193 priv = led_pwm_create_of(pdev); 193 priv = led_pwm_create_of(pdev);
194 if (!priv) 194 if (!priv)
195 return -ENODEV; 195 return -ENODEV;
196 } 196 }
197 197
198 platform_set_drvdata(pdev, priv); 198 platform_set_drvdata(pdev, priv);
199 199
200 return 0; 200 return 0;
201 201
202 err: 202 err:
203 while (i--) 203 while (i--)
204 led_classdev_unregister(&priv->leds[i].cdev); 204 led_classdev_unregister(&priv->leds[i].cdev);
205 205
206 return ret; 206 return ret;
207 } 207 }
208 208
209 static int led_pwm_remove(struct platform_device *pdev) 209 static int led_pwm_remove(struct platform_device *pdev)
210 { 210 {
211 struct led_pwm_priv *priv = platform_get_drvdata(pdev); 211 struct led_pwm_priv *priv = platform_get_drvdata(pdev);
212 int i; 212 int i;
213 213
214 for (i = 0; i < priv->num_leds; i++) { 214 for (i = 0; i < priv->num_leds; i++) {
215 led_classdev_unregister(&priv->leds[i].cdev); 215 led_classdev_unregister(&priv->leds[i].cdev);
216 if (priv->leds[i].can_sleep) 216 if (priv->leds[i].can_sleep)
217 cancel_work_sync(&priv->leds[i].work); 217 cancel_work_sync(&priv->leds[i].work);
218 } 218 }
219 219
220 return 0; 220 return 0;
221 } 221 }
222 222
223 static const struct of_device_id of_pwm_leds_match[] = { 223 static const struct of_device_id of_pwm_leds_match[] = {
224 { .compatible = "pwm-leds", }, 224 { .compatible = "pwm-leds", },
225 {}, 225 {},
226 }; 226 };
227 MODULE_DEVICE_TABLE(of, of_pwm_leds_match); 227 MODULE_DEVICE_TABLE(of, of_pwm_leds_match);
228 228
229 static struct platform_driver led_pwm_driver = { 229 static struct platform_driver led_pwm_driver = {
230 .probe = led_pwm_probe, 230 .probe = led_pwm_probe,
231 .remove = led_pwm_remove, 231 .remove = led_pwm_remove,
232 .driver = { 232 .driver = {
233 .name = "leds_pwm", 233 .name = "leds_pwm",
234 .owner = THIS_MODULE, 234 .owner = THIS_MODULE,
235 .of_match_table = of_match_ptr(of_pwm_leds_match), 235 .of_match_table = of_match_ptr(of_pwm_leds_match),
236 }, 236 },
237 }; 237 };
238 238
239 module_platform_driver(led_pwm_driver); 239 module_platform_driver(led_pwm_driver);
240 240
241 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>"); 241 MODULE_AUTHOR("Luotao Fu <l.fu@pengutronix.de>");
242 MODULE_DESCRIPTION("PWM LED driver for PXA"); 242 MODULE_DESCRIPTION("PWM LED driver for PXA");
243 MODULE_LICENSE("GPL"); 243 MODULE_LICENSE("GPL");
244 MODULE_ALIAS("platform:leds-pwm"); 244 MODULE_ALIAS("platform:leds-pwm");
245 245
drivers/leds/leds-regulator.c
1 /* 1 /*
2 * leds-regulator.c - LED class driver for regulator driven LEDs. 2 * leds-regulator.c - LED class driver for regulator driven LEDs.
3 * 3 *
4 * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it> 4 * Copyright (C) 2009 Antonio Ospite <ospite@studenti.unina.it>
5 * 5 *
6 * Inspired by leds-wm8350 driver. 6 * Inspired by leds-wm8350 driver.
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 * 11 *
12 */ 12 */
13 13
14 #include <linux/module.h> 14 #include <linux/module.h>
15 #include <linux/err.h> 15 #include <linux/err.h>
16 #include <linux/slab.h> 16 #include <linux/slab.h>
17 #include <linux/workqueue.h> 17 #include <linux/workqueue.h>
18 #include <linux/leds.h> 18 #include <linux/leds.h>
19 #include <linux/leds-regulator.h> 19 #include <linux/leds-regulator.h>
20 #include <linux/platform_device.h> 20 #include <linux/platform_device.h>
21 #include <linux/regulator/consumer.h> 21 #include <linux/regulator/consumer.h>
22 22
23 #define to_regulator_led(led_cdev) \ 23 #define to_regulator_led(led_cdev) \
24 container_of(led_cdev, struct regulator_led, cdev) 24 container_of(led_cdev, struct regulator_led, cdev)
25 25
26 struct regulator_led { 26 struct regulator_led {
27 struct led_classdev cdev; 27 struct led_classdev cdev;
28 enum led_brightness value; 28 enum led_brightness value;
29 int enabled; 29 int enabled;
30 struct mutex mutex; 30 struct mutex mutex;
31 struct work_struct work; 31 struct work_struct work;
32 32
33 struct regulator *vcc; 33 struct regulator *vcc;
34 }; 34 };
35 35
36 static inline int led_regulator_get_max_brightness(struct regulator *supply) 36 static inline int led_regulator_get_max_brightness(struct regulator *supply)
37 { 37 {
38 int ret; 38 int ret;
39 int voltage = regulator_list_voltage(supply, 0); 39 int voltage = regulator_list_voltage(supply, 0);
40 40
41 if (voltage <= 0) 41 if (voltage <= 0)
42 return 1; 42 return 1;
43 43
44 /* even if regulator can't change voltages, 44 /* even if regulator can't change voltages,
45 * we still assume it can change status 45 * we still assume it can change status
46 * and the LED can be turned on and off. 46 * and the LED can be turned on and off.
47 */ 47 */
48 ret = regulator_set_voltage(supply, voltage, voltage); 48 ret = regulator_set_voltage(supply, voltage, voltage);
49 if (ret < 0) 49 if (ret < 0)
50 return 1; 50 return 1;
51 51
52 return regulator_count_voltages(supply); 52 return regulator_count_voltages(supply);
53 } 53 }
54 54
55 static int led_regulator_get_voltage(struct regulator *supply, 55 static int led_regulator_get_voltage(struct regulator *supply,
56 enum led_brightness brightness) 56 enum led_brightness brightness)
57 { 57 {
58 if (brightness == 0) 58 if (brightness == 0)
59 return -EINVAL; 59 return -EINVAL;
60 60
61 return regulator_list_voltage(supply, brightness - 1); 61 return regulator_list_voltage(supply, brightness - 1);
62 } 62 }
63 63
64 64
65 static void regulator_led_enable(struct regulator_led *led) 65 static void regulator_led_enable(struct regulator_led *led)
66 { 66 {
67 int ret; 67 int ret;
68 68
69 if (led->enabled) 69 if (led->enabled)
70 return; 70 return;
71 71
72 ret = regulator_enable(led->vcc); 72 ret = regulator_enable(led->vcc);
73 if (ret != 0) { 73 if (ret != 0) {
74 dev_err(led->cdev.dev, "Failed to enable vcc: %d\n", ret); 74 dev_err(led->cdev.dev, "Failed to enable vcc: %d\n", ret);
75 return; 75 return;
76 } 76 }
77 77
78 led->enabled = 1; 78 led->enabled = 1;
79 } 79 }
80 80
81 static void regulator_led_disable(struct regulator_led *led) 81 static void regulator_led_disable(struct regulator_led *led)
82 { 82 {
83 int ret; 83 int ret;
84 84
85 if (!led->enabled) 85 if (!led->enabled)
86 return; 86 return;
87 87
88 ret = regulator_disable(led->vcc); 88 ret = regulator_disable(led->vcc);
89 if (ret != 0) { 89 if (ret != 0) {
90 dev_err(led->cdev.dev, "Failed to disable vcc: %d\n", ret); 90 dev_err(led->cdev.dev, "Failed to disable vcc: %d\n", ret);
91 return; 91 return;
92 } 92 }
93 93
94 led->enabled = 0; 94 led->enabled = 0;
95 } 95 }
96 96
97 static void regulator_led_set_value(struct regulator_led *led) 97 static void regulator_led_set_value(struct regulator_led *led)
98 { 98 {
99 int voltage; 99 int voltage;
100 int ret; 100 int ret;
101 101
102 mutex_lock(&led->mutex); 102 mutex_lock(&led->mutex);
103 103
104 if (led->value == LED_OFF) { 104 if (led->value == LED_OFF) {
105 regulator_led_disable(led); 105 regulator_led_disable(led);
106 goto out; 106 goto out;
107 } 107 }
108 108
109 if (led->cdev.max_brightness > 1) { 109 if (led->cdev.max_brightness > 1) {
110 voltage = led_regulator_get_voltage(led->vcc, led->value); 110 voltage = led_regulator_get_voltage(led->vcc, led->value);
111 dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n", 111 dev_dbg(led->cdev.dev, "brightness: %d voltage: %d\n",
112 led->value, voltage); 112 led->value, voltage);
113 113
114 ret = regulator_set_voltage(led->vcc, voltage, voltage); 114 ret = regulator_set_voltage(led->vcc, voltage, voltage);
115 if (ret != 0) 115 if (ret != 0)
116 dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n", 116 dev_err(led->cdev.dev, "Failed to set voltage %d: %d\n",
117 voltage, ret); 117 voltage, ret);
118 } 118 }
119 119
120 regulator_led_enable(led); 120 regulator_led_enable(led);
121 121
122 out: 122 out:
123 mutex_unlock(&led->mutex); 123 mutex_unlock(&led->mutex);
124 } 124 }
125 125
126 static void led_work(struct work_struct *work) 126 static void led_work(struct work_struct *work)
127 { 127 {
128 struct regulator_led *led; 128 struct regulator_led *led;
129 129
130 led = container_of(work, struct regulator_led, work); 130 led = container_of(work, struct regulator_led, work);
131 regulator_led_set_value(led); 131 regulator_led_set_value(led);
132 } 132 }
133 133
134 static void regulator_led_brightness_set(struct led_classdev *led_cdev, 134 static void regulator_led_brightness_set(struct led_classdev *led_cdev,
135 enum led_brightness value) 135 enum led_brightness value)
136 { 136 {
137 struct regulator_led *led = to_regulator_led(led_cdev); 137 struct regulator_led *led = to_regulator_led(led_cdev);
138 138
139 led->value = value; 139 led->value = value;
140 schedule_work(&led->work); 140 schedule_work(&led->work);
141 } 141 }
142 142
143 static int regulator_led_probe(struct platform_device *pdev) 143 static int regulator_led_probe(struct platform_device *pdev)
144 { 144 {
145 struct led_regulator_platform_data *pdata = pdev->dev.platform_data; 145 struct led_regulator_platform_data *pdata =
146 dev_get_platdata(&pdev->dev);
146 struct regulator_led *led; 147 struct regulator_led *led;
147 struct regulator *vcc; 148 struct regulator *vcc;
148 int ret = 0; 149 int ret = 0;
149 150
150 if (pdata == NULL) { 151 if (pdata == NULL) {
151 dev_err(&pdev->dev, "no platform data\n"); 152 dev_err(&pdev->dev, "no platform data\n");
152 return -ENODEV; 153 return -ENODEV;
153 } 154 }
154 155
155 vcc = regulator_get_exclusive(&pdev->dev, "vled"); 156 vcc = regulator_get_exclusive(&pdev->dev, "vled");
156 if (IS_ERR(vcc)) { 157 if (IS_ERR(vcc)) {
157 dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name); 158 dev_err(&pdev->dev, "Cannot get vcc for %s\n", pdata->name);
158 return PTR_ERR(vcc); 159 return PTR_ERR(vcc);
159 } 160 }
160 161
161 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); 162 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
162 if (led == NULL) { 163 if (led == NULL) {
163 ret = -ENOMEM; 164 ret = -ENOMEM;
164 goto err_vcc; 165 goto err_vcc;
165 } 166 }
166 167
167 led->cdev.max_brightness = led_regulator_get_max_brightness(vcc); 168 led->cdev.max_brightness = led_regulator_get_max_brightness(vcc);
168 if (pdata->brightness > led->cdev.max_brightness) { 169 if (pdata->brightness > led->cdev.max_brightness) {
169 dev_err(&pdev->dev, "Invalid default brightness %d\n", 170 dev_err(&pdev->dev, "Invalid default brightness %d\n",
170 pdata->brightness); 171 pdata->brightness);
171 ret = -EINVAL; 172 ret = -EINVAL;
172 goto err_vcc; 173 goto err_vcc;
173 } 174 }
174 led->value = pdata->brightness; 175 led->value = pdata->brightness;
175 176
176 led->cdev.brightness_set = regulator_led_brightness_set; 177 led->cdev.brightness_set = regulator_led_brightness_set;
177 led->cdev.name = pdata->name; 178 led->cdev.name = pdata->name;
178 led->cdev.flags |= LED_CORE_SUSPENDRESUME; 179 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
179 led->vcc = vcc; 180 led->vcc = vcc;
180 181
181 /* to handle correctly an already enabled regulator */ 182 /* to handle correctly an already enabled regulator */
182 if (regulator_is_enabled(led->vcc)) 183 if (regulator_is_enabled(led->vcc))
183 led->enabled = 1; 184 led->enabled = 1;
184 185
185 mutex_init(&led->mutex); 186 mutex_init(&led->mutex);
186 INIT_WORK(&led->work, led_work); 187 INIT_WORK(&led->work, led_work);
187 188
188 platform_set_drvdata(pdev, led); 189 platform_set_drvdata(pdev, led);
189 190
190 ret = led_classdev_register(&pdev->dev, &led->cdev); 191 ret = led_classdev_register(&pdev->dev, &led->cdev);
191 if (ret < 0) { 192 if (ret < 0) {
192 cancel_work_sync(&led->work); 193 cancel_work_sync(&led->work);
193 goto err_vcc; 194 goto err_vcc;
194 } 195 }
195 196
196 /* to expose the default value to userspace */ 197 /* to expose the default value to userspace */
197 led->cdev.brightness = led->value; 198 led->cdev.brightness = led->value;
198 199
199 /* Set the default led status */ 200 /* Set the default led status */
200 regulator_led_set_value(led); 201 regulator_led_set_value(led);
201 202
202 return 0; 203 return 0;
203 204
204 err_vcc: 205 err_vcc:
205 regulator_put(vcc); 206 regulator_put(vcc);
206 return ret; 207 return ret;
207 } 208 }
208 209
209 static int regulator_led_remove(struct platform_device *pdev) 210 static int regulator_led_remove(struct platform_device *pdev)
210 { 211 {
211 struct regulator_led *led = platform_get_drvdata(pdev); 212 struct regulator_led *led = platform_get_drvdata(pdev);
212 213
213 led_classdev_unregister(&led->cdev); 214 led_classdev_unregister(&led->cdev);
214 cancel_work_sync(&led->work); 215 cancel_work_sync(&led->work);
215 regulator_led_disable(led); 216 regulator_led_disable(led);
216 regulator_put(led->vcc); 217 regulator_put(led->vcc);
217 return 0; 218 return 0;
218 } 219 }
219 220
220 static struct platform_driver regulator_led_driver = { 221 static struct platform_driver regulator_led_driver = {
221 .driver = { 222 .driver = {
222 .name = "leds-regulator", 223 .name = "leds-regulator",
223 .owner = THIS_MODULE, 224 .owner = THIS_MODULE,
224 }, 225 },
225 .probe = regulator_led_probe, 226 .probe = regulator_led_probe,
226 .remove = regulator_led_remove, 227 .remove = regulator_led_remove,
227 }; 228 };
228 229
229 module_platform_driver(regulator_led_driver); 230 module_platform_driver(regulator_led_driver);
230 231
231 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>"); 232 MODULE_AUTHOR("Antonio Ospite <ospite@studenti.unina.it>");
232 MODULE_DESCRIPTION("Regulator driven LED driver"); 233 MODULE_DESCRIPTION("Regulator driven LED driver");
233 MODULE_LICENSE("GPL"); 234 MODULE_LICENSE("GPL");
234 MODULE_ALIAS("platform:leds-regulator"); 235 MODULE_ALIAS("platform:leds-regulator");
235 236
drivers/leds/leds-renesas-tpu.c
1 /* 1 /*
2 * LED control using Renesas TPU 2 * LED control using Renesas TPU
3 * 3 *
4 * Copyright (C) 2011 Magnus Damm 4 * Copyright (C) 2011 Magnus Damm
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License 8 * the Free Software Foundation; either version 2 of the License
9 * 9 *
10 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details. 13 * GNU General Public License for more details.
14 * 14 *
15 * You should have received a copy of the GNU General Public License 15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software 16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20 #include <linux/module.h> 20 #include <linux/module.h>
21 #include <linux/init.h> 21 #include <linux/init.h>
22 #include <linux/platform_device.h> 22 #include <linux/platform_device.h>
23 #include <linux/spinlock.h> 23 #include <linux/spinlock.h>
24 #include <linux/printk.h> 24 #include <linux/printk.h>
25 #include <linux/ioport.h> 25 #include <linux/ioport.h>
26 #include <linux/io.h> 26 #include <linux/io.h>
27 #include <linux/clk.h> 27 #include <linux/clk.h>
28 #include <linux/leds.h> 28 #include <linux/leds.h>
29 #include <linux/platform_data/leds-renesas-tpu.h> 29 #include <linux/platform_data/leds-renesas-tpu.h>
30 #include <linux/gpio.h> 30 #include <linux/gpio.h>
31 #include <linux/err.h> 31 #include <linux/err.h>
32 #include <linux/slab.h> 32 #include <linux/slab.h>
33 #include <linux/pm_runtime.h> 33 #include <linux/pm_runtime.h>
34 #include <linux/workqueue.h> 34 #include <linux/workqueue.h>
35 35
36 enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN }; 36 enum r_tpu_pin { R_TPU_PIN_UNUSED, R_TPU_PIN_GPIO, R_TPU_PIN_GPIO_FN };
37 enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON }; 37 enum r_tpu_timer { R_TPU_TIMER_UNUSED, R_TPU_TIMER_ON };
38 38
39 struct r_tpu_priv { 39 struct r_tpu_priv {
40 struct led_classdev ldev; 40 struct led_classdev ldev;
41 void __iomem *mapbase; 41 void __iomem *mapbase;
42 struct clk *clk; 42 struct clk *clk;
43 struct platform_device *pdev; 43 struct platform_device *pdev;
44 enum r_tpu_pin pin_state; 44 enum r_tpu_pin pin_state;
45 enum r_tpu_timer timer_state; 45 enum r_tpu_timer timer_state;
46 unsigned long min_rate; 46 unsigned long min_rate;
47 unsigned int refresh_rate; 47 unsigned int refresh_rate;
48 struct work_struct work; 48 struct work_struct work;
49 enum led_brightness new_brightness; 49 enum led_brightness new_brightness;
50 }; 50 };
51 51
52 static DEFINE_SPINLOCK(r_tpu_lock); 52 static DEFINE_SPINLOCK(r_tpu_lock);
53 53
54 #define TSTR -1 /* Timer start register (shared register) */ 54 #define TSTR -1 /* Timer start register (shared register) */
55 #define TCR 0 /* Timer control register (+0x00) */ 55 #define TCR 0 /* Timer control register (+0x00) */
56 #define TMDR 1 /* Timer mode register (+0x04) */ 56 #define TMDR 1 /* Timer mode register (+0x04) */
57 #define TIOR 2 /* Timer I/O control register (+0x08) */ 57 #define TIOR 2 /* Timer I/O control register (+0x08) */
58 #define TIER 3 /* Timer interrupt enable register (+0x0c) */ 58 #define TIER 3 /* Timer interrupt enable register (+0x0c) */
59 #define TSR 4 /* Timer status register (+0x10) */ 59 #define TSR 4 /* Timer status register (+0x10) */
60 #define TCNT 5 /* Timer counter (+0x14) */ 60 #define TCNT 5 /* Timer counter (+0x14) */
61 #define TGRA 6 /* Timer general register A (+0x18) */ 61 #define TGRA 6 /* Timer general register A (+0x18) */
62 #define TGRB 7 /* Timer general register B (+0x1c) */ 62 #define TGRB 7 /* Timer general register B (+0x1c) */
63 #define TGRC 8 /* Timer general register C (+0x20) */ 63 #define TGRC 8 /* Timer general register C (+0x20) */
64 #define TGRD 9 /* Timer general register D (+0x24) */ 64 #define TGRD 9 /* Timer general register D (+0x24) */
65 65
66 static inline u16 r_tpu_read(struct r_tpu_priv *p, int reg_nr) 66 static inline u16 r_tpu_read(struct r_tpu_priv *p, int reg_nr)
67 { 67 {
68 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; 68 struct led_renesas_tpu_config *cfg = dev_get_platdata(&p->pdev->dev);
69 void __iomem *base = p->mapbase; 69 void __iomem *base = p->mapbase;
70 unsigned long offs = reg_nr << 2; 70 unsigned long offs = reg_nr << 2;
71 71
72 if (reg_nr == TSTR) 72 if (reg_nr == TSTR)
73 return ioread16(base - cfg->channel_offset); 73 return ioread16(base - cfg->channel_offset);
74 74
75 return ioread16(base + offs); 75 return ioread16(base + offs);
76 } 76 }
77 77
78 static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr, u16 value) 78 static inline void r_tpu_write(struct r_tpu_priv *p, int reg_nr, u16 value)
79 { 79 {
80 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; 80 struct led_renesas_tpu_config *cfg = dev_get_platdata(&p->pdev->dev);
81 void __iomem *base = p->mapbase; 81 void __iomem *base = p->mapbase;
82 unsigned long offs = reg_nr << 2; 82 unsigned long offs = reg_nr << 2;
83 83
84 if (reg_nr == TSTR) { 84 if (reg_nr == TSTR) {
85 iowrite16(value, base - cfg->channel_offset); 85 iowrite16(value, base - cfg->channel_offset);
86 return; 86 return;
87 } 87 }
88 88
89 iowrite16(value, base + offs); 89 iowrite16(value, base + offs);
90 } 90 }
91 91
92 static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start) 92 static void r_tpu_start_stop_ch(struct r_tpu_priv *p, int start)
93 { 93 {
94 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; 94 struct led_renesas_tpu_config *cfg = dev_get_platdata(&p->pdev->dev);
95 unsigned long flags; 95 unsigned long flags;
96 u16 value; 96 u16 value;
97 97
98 /* start stop register shared by multiple timer channels */ 98 /* start stop register shared by multiple timer channels */
99 spin_lock_irqsave(&r_tpu_lock, flags); 99 spin_lock_irqsave(&r_tpu_lock, flags);
100 value = r_tpu_read(p, TSTR); 100 value = r_tpu_read(p, TSTR);
101 101
102 if (start) 102 if (start)
103 value |= 1 << cfg->timer_bit; 103 value |= 1 << cfg->timer_bit;
104 else 104 else
105 value &= ~(1 << cfg->timer_bit); 105 value &= ~(1 << cfg->timer_bit);
106 106
107 r_tpu_write(p, TSTR, value); 107 r_tpu_write(p, TSTR, value);
108 spin_unlock_irqrestore(&r_tpu_lock, flags); 108 spin_unlock_irqrestore(&r_tpu_lock, flags);
109 } 109 }
110 110
111 static int r_tpu_enable(struct r_tpu_priv *p, enum led_brightness brightness) 111 static int r_tpu_enable(struct r_tpu_priv *p, enum led_brightness brightness)
112 { 112 {
113 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; 113 struct led_renesas_tpu_config *cfg = dev_get_platdata(&p->pdev->dev);
114 int prescaler[] = { 1, 4, 16, 64 }; 114 int prescaler[] = { 1, 4, 16, 64 };
115 int k, ret; 115 int k, ret;
116 unsigned long rate, tmp; 116 unsigned long rate, tmp;
117 117
118 if (p->timer_state == R_TPU_TIMER_ON) 118 if (p->timer_state == R_TPU_TIMER_ON)
119 return 0; 119 return 0;
120 120
121 /* wake up device and enable clock */ 121 /* wake up device and enable clock */
122 pm_runtime_get_sync(&p->pdev->dev); 122 pm_runtime_get_sync(&p->pdev->dev);
123 ret = clk_enable(p->clk); 123 ret = clk_enable(p->clk);
124 if (ret) { 124 if (ret) {
125 dev_err(&p->pdev->dev, "cannot enable clock\n"); 125 dev_err(&p->pdev->dev, "cannot enable clock\n");
126 return ret; 126 return ret;
127 } 127 }
128 128
129 /* make sure channel is disabled */ 129 /* make sure channel is disabled */
130 r_tpu_start_stop_ch(p, 0); 130 r_tpu_start_stop_ch(p, 0);
131 131
132 /* get clock rate after enabling it */ 132 /* get clock rate after enabling it */
133 rate = clk_get_rate(p->clk); 133 rate = clk_get_rate(p->clk);
134 134
135 /* pick the lowest acceptable rate */ 135 /* pick the lowest acceptable rate */
136 for (k = ARRAY_SIZE(prescaler) - 1; k >= 0; k--) 136 for (k = ARRAY_SIZE(prescaler) - 1; k >= 0; k--)
137 if ((rate / prescaler[k]) >= p->min_rate) 137 if ((rate / prescaler[k]) >= p->min_rate)
138 break; 138 break;
139 139
140 if (k < 0) { 140 if (k < 0) {
141 dev_err(&p->pdev->dev, "clock rate mismatch\n"); 141 dev_err(&p->pdev->dev, "clock rate mismatch\n");
142 goto err0; 142 goto err0;
143 } 143 }
144 dev_dbg(&p->pdev->dev, "rate = %lu, prescaler %u\n", 144 dev_dbg(&p->pdev->dev, "rate = %lu, prescaler %u\n",
145 rate, prescaler[k]); 145 rate, prescaler[k]);
146 146
147 /* clear TCNT on TGRB match, count on rising edge, set prescaler */ 147 /* clear TCNT on TGRB match, count on rising edge, set prescaler */
148 r_tpu_write(p, TCR, 0x0040 | k); 148 r_tpu_write(p, TCR, 0x0040 | k);
149 149
150 /* output 0 until TGRA, output 1 until TGRB */ 150 /* output 0 until TGRA, output 1 until TGRB */
151 r_tpu_write(p, TIOR, 0x0002); 151 r_tpu_write(p, TIOR, 0x0002);
152 152
153 rate /= prescaler[k] * p->refresh_rate; 153 rate /= prescaler[k] * p->refresh_rate;
154 r_tpu_write(p, TGRB, rate); 154 r_tpu_write(p, TGRB, rate);
155 dev_dbg(&p->pdev->dev, "TRGB = 0x%04lx\n", rate); 155 dev_dbg(&p->pdev->dev, "TRGB = 0x%04lx\n", rate);
156 156
157 tmp = (cfg->max_brightness - brightness) * rate; 157 tmp = (cfg->max_brightness - brightness) * rate;
158 r_tpu_write(p, TGRA, tmp / cfg->max_brightness); 158 r_tpu_write(p, TGRA, tmp / cfg->max_brightness);
159 dev_dbg(&p->pdev->dev, "TRGA = 0x%04lx\n", tmp / cfg->max_brightness); 159 dev_dbg(&p->pdev->dev, "TRGA = 0x%04lx\n", tmp / cfg->max_brightness);
160 160
161 /* PWM mode */ 161 /* PWM mode */
162 r_tpu_write(p, TMDR, 0x0002); 162 r_tpu_write(p, TMDR, 0x0002);
163 163
164 /* enable channel */ 164 /* enable channel */
165 r_tpu_start_stop_ch(p, 1); 165 r_tpu_start_stop_ch(p, 1);
166 166
167 p->timer_state = R_TPU_TIMER_ON; 167 p->timer_state = R_TPU_TIMER_ON;
168 return 0; 168 return 0;
169 err0: 169 err0:
170 clk_disable(p->clk); 170 clk_disable(p->clk);
171 pm_runtime_put_sync(&p->pdev->dev); 171 pm_runtime_put_sync(&p->pdev->dev);
172 return -ENOTSUPP; 172 return -ENOTSUPP;
173 } 173 }
174 174
175 static void r_tpu_disable(struct r_tpu_priv *p) 175 static void r_tpu_disable(struct r_tpu_priv *p)
176 { 176 {
177 if (p->timer_state == R_TPU_TIMER_UNUSED) 177 if (p->timer_state == R_TPU_TIMER_UNUSED)
178 return; 178 return;
179 179
180 /* disable channel */ 180 /* disable channel */
181 r_tpu_start_stop_ch(p, 0); 181 r_tpu_start_stop_ch(p, 0);
182 182
183 /* stop clock and mark device as idle */ 183 /* stop clock and mark device as idle */
184 clk_disable(p->clk); 184 clk_disable(p->clk);
185 pm_runtime_put_sync(&p->pdev->dev); 185 pm_runtime_put_sync(&p->pdev->dev);
186 186
187 p->timer_state = R_TPU_TIMER_UNUSED; 187 p->timer_state = R_TPU_TIMER_UNUSED;
188 } 188 }
189 189
190 static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state, 190 static void r_tpu_set_pin(struct r_tpu_priv *p, enum r_tpu_pin new_state,
191 enum led_brightness brightness) 191 enum led_brightness brightness)
192 { 192 {
193 struct led_renesas_tpu_config *cfg = p->pdev->dev.platform_data; 193 struct led_renesas_tpu_config *cfg = dev_get_platdata(&p->pdev->dev);
194 194
195 if (p->pin_state == new_state) { 195 if (p->pin_state == new_state) {
196 if (p->pin_state == R_TPU_PIN_GPIO) 196 if (p->pin_state == R_TPU_PIN_GPIO)
197 gpio_set_value(cfg->pin_gpio, brightness); 197 gpio_set_value(cfg->pin_gpio, brightness);
198 return; 198 return;
199 } 199 }
200 200
201 if (p->pin_state == R_TPU_PIN_GPIO) 201 if (p->pin_state == R_TPU_PIN_GPIO)
202 gpio_free(cfg->pin_gpio); 202 gpio_free(cfg->pin_gpio);
203 203
204 if (p->pin_state == R_TPU_PIN_GPIO_FN) 204 if (p->pin_state == R_TPU_PIN_GPIO_FN)
205 gpio_free(cfg->pin_gpio_fn); 205 gpio_free(cfg->pin_gpio_fn);
206 206
207 if (new_state == R_TPU_PIN_GPIO) 207 if (new_state == R_TPU_PIN_GPIO)
208 gpio_request_one(cfg->pin_gpio, !!brightness ? 208 gpio_request_one(cfg->pin_gpio, !!brightness ?
209 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW, 209 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
210 cfg->name); 210 cfg->name);
211 211
212 if (new_state == R_TPU_PIN_GPIO_FN) 212 if (new_state == R_TPU_PIN_GPIO_FN)
213 gpio_request(cfg->pin_gpio_fn, cfg->name); 213 gpio_request(cfg->pin_gpio_fn, cfg->name);
214 214
215 p->pin_state = new_state; 215 p->pin_state = new_state;
216 } 216 }
217 217
218 static void r_tpu_work(struct work_struct *work) 218 static void r_tpu_work(struct work_struct *work)
219 { 219 {
220 struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work); 220 struct r_tpu_priv *p = container_of(work, struct r_tpu_priv, work);
221 enum led_brightness brightness = p->new_brightness; 221 enum led_brightness brightness = p->new_brightness;
222 222
223 r_tpu_disable(p); 223 r_tpu_disable(p);
224 224
225 /* off and maximum are handled as GPIO pins, in between PWM */ 225 /* off and maximum are handled as GPIO pins, in between PWM */
226 if ((brightness == 0) || (brightness == p->ldev.max_brightness)) 226 if ((brightness == 0) || (brightness == p->ldev.max_brightness))
227 r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness); 227 r_tpu_set_pin(p, R_TPU_PIN_GPIO, brightness);
228 else { 228 else {
229 r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0); 229 r_tpu_set_pin(p, R_TPU_PIN_GPIO_FN, 0);
230 r_tpu_enable(p, brightness); 230 r_tpu_enable(p, brightness);
231 } 231 }
232 } 232 }
233 233
234 static void r_tpu_set_brightness(struct led_classdev *ldev, 234 static void r_tpu_set_brightness(struct led_classdev *ldev,
235 enum led_brightness brightness) 235 enum led_brightness brightness)
236 { 236 {
237 struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev); 237 struct r_tpu_priv *p = container_of(ldev, struct r_tpu_priv, ldev);
238 p->new_brightness = brightness; 238 p->new_brightness = brightness;
239 schedule_work(&p->work); 239 schedule_work(&p->work);
240 } 240 }
241 241
242 static int r_tpu_probe(struct platform_device *pdev) 242 static int r_tpu_probe(struct platform_device *pdev)
243 { 243 {
244 struct led_renesas_tpu_config *cfg = pdev->dev.platform_data; 244 struct led_renesas_tpu_config *cfg = dev_get_platdata(&pdev->dev);
245 struct r_tpu_priv *p; 245 struct r_tpu_priv *p;
246 struct resource *res; 246 struct resource *res;
247 int ret; 247 int ret;
248 248
249 if (!cfg) { 249 if (!cfg) {
250 dev_err(&pdev->dev, "missing platform data\n"); 250 dev_err(&pdev->dev, "missing platform data\n");
251 return -ENODEV; 251 return -ENODEV;
252 } 252 }
253 253
254 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); 254 p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL);
255 if (p == NULL) { 255 if (p == NULL) {
256 dev_err(&pdev->dev, "failed to allocate driver data\n"); 256 dev_err(&pdev->dev, "failed to allocate driver data\n");
257 return -ENOMEM; 257 return -ENOMEM;
258 } 258 }
259 259
260 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 260 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
261 if (!res) { 261 if (!res) {
262 dev_err(&pdev->dev, "failed to get I/O memory\n"); 262 dev_err(&pdev->dev, "failed to get I/O memory\n");
263 return -ENXIO; 263 return -ENXIO;
264 } 264 }
265 265
266 /* map memory, let mapbase point to our channel */ 266 /* map memory, let mapbase point to our channel */
267 p->mapbase = devm_ioremap_nocache(&pdev->dev, res->start, 267 p->mapbase = devm_ioremap_nocache(&pdev->dev, res->start,
268 resource_size(res)); 268 resource_size(res));
269 if (p->mapbase == NULL) { 269 if (p->mapbase == NULL) {
270 dev_err(&pdev->dev, "failed to remap I/O memory\n"); 270 dev_err(&pdev->dev, "failed to remap I/O memory\n");
271 return -ENXIO; 271 return -ENXIO;
272 } 272 }
273 273
274 /* get hold of clock */ 274 /* get hold of clock */
275 p->clk = devm_clk_get(&pdev->dev, NULL); 275 p->clk = devm_clk_get(&pdev->dev, NULL);
276 if (IS_ERR(p->clk)) { 276 if (IS_ERR(p->clk)) {
277 dev_err(&pdev->dev, "cannot get clock\n"); 277 dev_err(&pdev->dev, "cannot get clock\n");
278 return PTR_ERR(p->clk); 278 return PTR_ERR(p->clk);
279 } 279 }
280 280
281 p->pdev = pdev; 281 p->pdev = pdev;
282 p->pin_state = R_TPU_PIN_UNUSED; 282 p->pin_state = R_TPU_PIN_UNUSED;
283 p->timer_state = R_TPU_TIMER_UNUSED; 283 p->timer_state = R_TPU_TIMER_UNUSED;
284 p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100; 284 p->refresh_rate = cfg->refresh_rate ? cfg->refresh_rate : 100;
285 r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF); 285 r_tpu_set_pin(p, R_TPU_PIN_GPIO, LED_OFF);
286 platform_set_drvdata(pdev, p); 286 platform_set_drvdata(pdev, p);
287 287
288 INIT_WORK(&p->work, r_tpu_work); 288 INIT_WORK(&p->work, r_tpu_work);
289 289
290 p->ldev.name = cfg->name; 290 p->ldev.name = cfg->name;
291 p->ldev.brightness = LED_OFF; 291 p->ldev.brightness = LED_OFF;
292 p->ldev.max_brightness = cfg->max_brightness; 292 p->ldev.max_brightness = cfg->max_brightness;
293 p->ldev.brightness_set = r_tpu_set_brightness; 293 p->ldev.brightness_set = r_tpu_set_brightness;
294 p->ldev.flags |= LED_CORE_SUSPENDRESUME; 294 p->ldev.flags |= LED_CORE_SUSPENDRESUME;
295 ret = led_classdev_register(&pdev->dev, &p->ldev); 295 ret = led_classdev_register(&pdev->dev, &p->ldev);
296 if (ret < 0) 296 if (ret < 0)
297 goto err0; 297 goto err0;
298 298
299 /* max_brightness may be updated by the LED core code */ 299 /* max_brightness may be updated by the LED core code */
300 p->min_rate = p->ldev.max_brightness * p->refresh_rate; 300 p->min_rate = p->ldev.max_brightness * p->refresh_rate;
301 301
302 pm_runtime_enable(&pdev->dev); 302 pm_runtime_enable(&pdev->dev);
303 return 0; 303 return 0;
304 304
305 err0: 305 err0:
306 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); 306 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
307 return ret; 307 return ret;
308 } 308 }
309 309
310 static int r_tpu_remove(struct platform_device *pdev) 310 static int r_tpu_remove(struct platform_device *pdev)
311 { 311 {
312 struct r_tpu_priv *p = platform_get_drvdata(pdev); 312 struct r_tpu_priv *p = platform_get_drvdata(pdev);
313 313
314 r_tpu_set_brightness(&p->ldev, LED_OFF); 314 r_tpu_set_brightness(&p->ldev, LED_OFF);
315 led_classdev_unregister(&p->ldev); 315 led_classdev_unregister(&p->ldev);
316 cancel_work_sync(&p->work); 316 cancel_work_sync(&p->work);
317 r_tpu_disable(p); 317 r_tpu_disable(p);
318 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF); 318 r_tpu_set_pin(p, R_TPU_PIN_UNUSED, LED_OFF);
319 319
320 pm_runtime_disable(&pdev->dev); 320 pm_runtime_disable(&pdev->dev);
321 321
322 return 0; 322 return 0;
323 } 323 }
324 324
325 static struct platform_driver r_tpu_device_driver = { 325 static struct platform_driver r_tpu_device_driver = {
326 .probe = r_tpu_probe, 326 .probe = r_tpu_probe,
327 .remove = r_tpu_remove, 327 .remove = r_tpu_remove,
328 .driver = { 328 .driver = {
329 .name = "leds-renesas-tpu", 329 .name = "leds-renesas-tpu",
330 } 330 }
331 }; 331 };
332 332
333 module_platform_driver(r_tpu_device_driver); 333 module_platform_driver(r_tpu_device_driver);
334 334
335 MODULE_AUTHOR("Magnus Damm"); 335 MODULE_AUTHOR("Magnus Damm");
336 MODULE_DESCRIPTION("Renesas TPU LED Driver"); 336 MODULE_DESCRIPTION("Renesas TPU LED Driver");
337 MODULE_LICENSE("GPL v2"); 337 MODULE_LICENSE("GPL v2");
338 338
drivers/leds/leds-s3c24xx.c
1 /* drivers/leds/leds-s3c24xx.c 1 /* drivers/leds/leds-s3c24xx.c
2 * 2 *
3 * (c) 2006 Simtec Electronics 3 * (c) 2006 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
5 * Ben Dooks <ben@simtec.co.uk> 5 * Ben Dooks <ben@simtec.co.uk>
6 * 6 *
7 * S3C24XX - LEDs GPIO driver 7 * S3C24XX - LEDs GPIO driver
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as 10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation. 11 * published by the Free Software Foundation.
12 */ 12 */
13 13
14 #include <linux/kernel.h> 14 #include <linux/kernel.h>
15 #include <linux/init.h> 15 #include <linux/init.h>
16 #include <linux/platform_device.h> 16 #include <linux/platform_device.h>
17 #include <linux/leds.h> 17 #include <linux/leds.h>
18 #include <linux/gpio.h> 18 #include <linux/gpio.h>
19 #include <linux/slab.h> 19 #include <linux/slab.h>
20 #include <linux/module.h> 20 #include <linux/module.h>
21 21
22 #include <mach/hardware.h> 22 #include <mach/hardware.h>
23 #include <mach/regs-gpio.h> 23 #include <mach/regs-gpio.h>
24 #include <linux/platform_data/leds-s3c24xx.h> 24 #include <linux/platform_data/leds-s3c24xx.h>
25 25
26 /* our context */ 26 /* our context */
27 27
28 struct s3c24xx_gpio_led { 28 struct s3c24xx_gpio_led {
29 struct led_classdev cdev; 29 struct led_classdev cdev;
30 struct s3c24xx_led_platdata *pdata; 30 struct s3c24xx_led_platdata *pdata;
31 }; 31 };
32 32
33 static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev) 33 static inline struct s3c24xx_gpio_led *pdev_to_gpio(struct platform_device *dev)
34 { 34 {
35 return platform_get_drvdata(dev); 35 return platform_get_drvdata(dev);
36 } 36 }
37 37
38 static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev) 38 static inline struct s3c24xx_gpio_led *to_gpio(struct led_classdev *led_cdev)
39 { 39 {
40 return container_of(led_cdev, struct s3c24xx_gpio_led, cdev); 40 return container_of(led_cdev, struct s3c24xx_gpio_led, cdev);
41 } 41 }
42 42
43 static void s3c24xx_led_set(struct led_classdev *led_cdev, 43 static void s3c24xx_led_set(struct led_classdev *led_cdev,
44 enum led_brightness value) 44 enum led_brightness value)
45 { 45 {
46 struct s3c24xx_gpio_led *led = to_gpio(led_cdev); 46 struct s3c24xx_gpio_led *led = to_gpio(led_cdev);
47 struct s3c24xx_led_platdata *pd = led->pdata; 47 struct s3c24xx_led_platdata *pd = led->pdata;
48 int state = (value ? 1 : 0) ^ (pd->flags & S3C24XX_LEDF_ACTLOW); 48 int state = (value ? 1 : 0) ^ (pd->flags & S3C24XX_LEDF_ACTLOW);
49 49
50 /* there will be a short delay between setting the output and 50 /* there will be a short delay between setting the output and
51 * going from output to input when using tristate. */ 51 * going from output to input when using tristate. */
52 52
53 gpio_set_value(pd->gpio, state); 53 gpio_set_value(pd->gpio, state);
54 54
55 if (pd->flags & S3C24XX_LEDF_TRISTATE) { 55 if (pd->flags & S3C24XX_LEDF_TRISTATE) {
56 if (value) 56 if (value)
57 gpio_direction_output(pd->gpio, state); 57 gpio_direction_output(pd->gpio, state);
58 else 58 else
59 gpio_direction_input(pd->gpio); 59 gpio_direction_input(pd->gpio);
60 } 60 }
61 } 61 }
62 62
63 static int s3c24xx_led_remove(struct platform_device *dev) 63 static int s3c24xx_led_remove(struct platform_device *dev)
64 { 64 {
65 struct s3c24xx_gpio_led *led = pdev_to_gpio(dev); 65 struct s3c24xx_gpio_led *led = pdev_to_gpio(dev);
66 66
67 led_classdev_unregister(&led->cdev); 67 led_classdev_unregister(&led->cdev);
68 68
69 return 0; 69 return 0;
70 } 70 }
71 71
72 static int s3c24xx_led_probe(struct platform_device *dev) 72 static int s3c24xx_led_probe(struct platform_device *dev)
73 { 73 {
74 struct s3c24xx_led_platdata *pdata = dev->dev.platform_data; 74 struct s3c24xx_led_platdata *pdata = dev_get_platdata(&dev->dev);
75 struct s3c24xx_gpio_led *led; 75 struct s3c24xx_gpio_led *led;
76 int ret; 76 int ret;
77 77
78 led = devm_kzalloc(&dev->dev, sizeof(struct s3c24xx_gpio_led), 78 led = devm_kzalloc(&dev->dev, sizeof(struct s3c24xx_gpio_led),
79 GFP_KERNEL); 79 GFP_KERNEL);
80 if (led == NULL) { 80 if (led == NULL) {
81 dev_err(&dev->dev, "No memory for device\n"); 81 dev_err(&dev->dev, "No memory for device\n");
82 return -ENOMEM; 82 return -ENOMEM;
83 } 83 }
84 84
85 platform_set_drvdata(dev, led); 85 platform_set_drvdata(dev, led);
86 86
87 led->cdev.brightness_set = s3c24xx_led_set; 87 led->cdev.brightness_set = s3c24xx_led_set;
88 led->cdev.default_trigger = pdata->def_trigger; 88 led->cdev.default_trigger = pdata->def_trigger;
89 led->cdev.name = pdata->name; 89 led->cdev.name = pdata->name;
90 led->cdev.flags |= LED_CORE_SUSPENDRESUME; 90 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
91 91
92 led->pdata = pdata; 92 led->pdata = pdata;
93 93
94 ret = devm_gpio_request(&dev->dev, pdata->gpio, "S3C24XX_LED"); 94 ret = devm_gpio_request(&dev->dev, pdata->gpio, "S3C24XX_LED");
95 if (ret < 0) 95 if (ret < 0)
96 return ret; 96 return ret;
97 97
98 /* no point in having a pull-up if we are always driving */ 98 /* no point in having a pull-up if we are always driving */
99 99
100 s3c_gpio_setpull(pdata->gpio, S3C_GPIO_PULL_NONE); 100 s3c_gpio_setpull(pdata->gpio, S3C_GPIO_PULL_NONE);
101 101
102 if (pdata->flags & S3C24XX_LEDF_TRISTATE) 102 if (pdata->flags & S3C24XX_LEDF_TRISTATE)
103 gpio_direction_input(pdata->gpio); 103 gpio_direction_input(pdata->gpio);
104 else 104 else
105 gpio_direction_output(pdata->gpio, 105 gpio_direction_output(pdata->gpio,
106 pdata->flags & S3C24XX_LEDF_ACTLOW ? 1 : 0); 106 pdata->flags & S3C24XX_LEDF_ACTLOW ? 1 : 0);
107 107
108 /* register our new led device */ 108 /* register our new led device */
109 109
110 ret = led_classdev_register(&dev->dev, &led->cdev); 110 ret = led_classdev_register(&dev->dev, &led->cdev);
111 if (ret < 0) 111 if (ret < 0)
112 dev_err(&dev->dev, "led_classdev_register failed\n"); 112 dev_err(&dev->dev, "led_classdev_register failed\n");
113 113
114 return ret; 114 return ret;
115 } 115 }
116 116
117 static struct platform_driver s3c24xx_led_driver = { 117 static struct platform_driver s3c24xx_led_driver = {
118 .probe = s3c24xx_led_probe, 118 .probe = s3c24xx_led_probe,
119 .remove = s3c24xx_led_remove, 119 .remove = s3c24xx_led_remove,
120 .driver = { 120 .driver = {
121 .name = "s3c24xx_led", 121 .name = "s3c24xx_led",
122 .owner = THIS_MODULE, 122 .owner = THIS_MODULE,
123 }, 123 },
124 }; 124 };
125 125
126 module_platform_driver(s3c24xx_led_driver); 126 module_platform_driver(s3c24xx_led_driver);
127 127
128 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); 128 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
129 MODULE_DESCRIPTION("S3C24XX LED driver"); 129 MODULE_DESCRIPTION("S3C24XX LED driver");
130 MODULE_LICENSE("GPL"); 130 MODULE_LICENSE("GPL");
131 MODULE_ALIAS("platform:s3c24xx_led"); 131 MODULE_ALIAS("platform:s3c24xx_led");
132 132
drivers/leds/leds-tca6507.c
1 /* 1 /*
2 * leds-tca6507 2 * leds-tca6507
3 * 3 *
4 * The TCA6507 is a programmable LED controller that can drive 7 4 * The TCA6507 is a programmable LED controller that can drive 7
5 * separate lines either by holding them low, or by pulsing them 5 * separate lines either by holding them low, or by pulsing them
6 * with modulated width. 6 * with modulated width.
7 * The modulation can be varied in a simple pattern to produce a blink or 7 * The modulation can be varied in a simple pattern to produce a blink or
8 * double-blink. 8 * double-blink.
9 * 9 *
10 * This driver can configure each line either as a 'GPIO' which is out-only 10 * This driver can configure each line either as a 'GPIO' which is out-only
11 * (no pull-up) or as an LED with variable brightness and hardware-assisted 11 * (no pull-up) or as an LED with variable brightness and hardware-assisted
12 * blinking. 12 * blinking.
13 * 13 *
14 * Apart from OFF and ON there are three programmable brightness levels which 14 * Apart from OFF and ON there are three programmable brightness levels which
15 * can be programmed from 0 to 15 and indicate how many 500usec intervals in 15 * can be programmed from 0 to 15 and indicate how many 500usec intervals in
16 * each 8msec that the led is 'on'. The levels are named MASTER, BANK0 and 16 * each 8msec that the led is 'on'. The levels are named MASTER, BANK0 and
17 * BANK1. 17 * BANK1.
18 * 18 *
19 * There are two different blink rates that can be programmed, each with 19 * There are two different blink rates that can be programmed, each with
20 * separate time for rise, on, fall, off and second-off. Thus if 3 or more 20 * separate time for rise, on, fall, off and second-off. Thus if 3 or more
21 * different non-trivial rates are required, software must be used for the extra 21 * different non-trivial rates are required, software must be used for the extra
22 * rates. The two different blink rates must align with the two levels BANK0 and 22 * rates. The two different blink rates must align with the two levels BANK0 and
23 * BANK1. 23 * BANK1.
24 * This driver does not support double-blink so 'second-off' always matches 24 * This driver does not support double-blink so 'second-off' always matches
25 * 'off'. 25 * 'off'.
26 * 26 *
27 * Only 16 different times can be programmed in a roughly logarithmic scale from 27 * Only 16 different times can be programmed in a roughly logarithmic scale from
28 * 64ms to 16320ms. To be precise the possible times are: 28 * 64ms to 16320ms. To be precise the possible times are:
29 * 0, 64, 128, 192, 256, 384, 512, 768, 29 * 0, 64, 128, 192, 256, 384, 512, 768,
30 * 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320 30 * 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
31 * 31 *
32 * Times that cannot be closely matched with these must be 32 * Times that cannot be closely matched with these must be
33 * handled in software. This driver allows 12.5% error in matching. 33 * handled in software. This driver allows 12.5% error in matching.
34 * 34 *
35 * This driver does not allow rise/fall rates to be set explicitly. When trying 35 * This driver does not allow rise/fall rates to be set explicitly. When trying
36 * to match a given 'on' or 'off' period, an appropriate pair of 'change' and 36 * to match a given 'on' or 'off' period, an appropriate pair of 'change' and
37 * 'hold' times are chosen to get a close match. If the target delay is even, 37 * 'hold' times are chosen to get a close match. If the target delay is even,
38 * the 'change' number will be the smaller; if odd, the 'hold' number will be 38 * the 'change' number will be the smaller; if odd, the 'hold' number will be
39 * the smaller. 39 * the smaller.
40 40
41 * Choosing pairs of delays with 12.5% errors allows us to match delays in the 41 * Choosing pairs of delays with 12.5% errors allows us to match delays in the
42 * ranges: 56-72, 112-144, 168-216, 224-27504, 28560-36720. 42 * ranges: 56-72, 112-144, 168-216, 224-27504, 28560-36720.
43 * 26% of the achievable sums can be matched by multiple pairings. For example 43 * 26% of the achievable sums can be matched by multiple pairings. For example
44 * 1536 == 1536+0, 1024+512, or 768+768. This driver will always choose the 44 * 1536 == 1536+0, 1024+512, or 768+768. This driver will always choose the
45 * pairing with the least maximum - 768+768 in this case. Other pairings are 45 * pairing with the least maximum - 768+768 in this case. Other pairings are
46 * not available. 46 * not available.
47 * 47 *
48 * Access to the 3 levels and 2 blinks are on a first-come, first-served basis. 48 * Access to the 3 levels and 2 blinks are on a first-come, first-served basis.
49 * Access can be shared by multiple leds if they have the same level and 49 * Access can be shared by multiple leds if they have the same level and
50 * either same blink rates, or some don't blink. 50 * either same blink rates, or some don't blink.
51 * When a led changes, it relinquishes access and tries again, so it might 51 * When a led changes, it relinquishes access and tries again, so it might
52 * lose access to hardware blink. 52 * lose access to hardware blink.
53 * If a blink engine cannot be allocated, software blink is used. 53 * If a blink engine cannot be allocated, software blink is used.
54 * If the desired brightness cannot be allocated, the closest available non-zero 54 * If the desired brightness cannot be allocated, the closest available non-zero
55 * brightness is used. As 'full' is always available, the worst case would be 55 * brightness is used. As 'full' is always available, the worst case would be
56 * to have two different blink rates at '1', with Max at '2', then other leds 56 * to have two different blink rates at '1', with Max at '2', then other leds
57 * will have to choose between '2' and '16'. Hopefully this is not likely. 57 * will have to choose between '2' and '16'. Hopefully this is not likely.
58 * 58 *
59 * Each bank (BANK0 and BANK1) has two usage counts - LEDs using the brightness 59 * Each bank (BANK0 and BANK1) has two usage counts - LEDs using the brightness
60 * and LEDs using the blink. It can only be reprogrammed when the appropriate 60 * and LEDs using the blink. It can only be reprogrammed when the appropriate
61 * counter is zero. The MASTER level has a single usage count. 61 * counter is zero. The MASTER level has a single usage count.
62 * 62 *
63 * Each Led has programmable 'on' and 'off' time as milliseconds. With each 63 * Each Led has programmable 'on' and 'off' time as milliseconds. With each
64 * there is a flag saying if it was explicitly requested or defaulted. 64 * there is a flag saying if it was explicitly requested or defaulted.
65 * Similarly the banks know if each time was explicit or a default. Defaults 65 * Similarly the banks know if each time was explicit or a default. Defaults
66 * are permitted to be changed freely - they are not recognised when matching. 66 * are permitted to be changed freely - they are not recognised when matching.
67 * 67 *
68 * 68 *
69 * An led-tca6507 device must be provided with platform data. This data 69 * An led-tca6507 device must be provided with platform data. This data
70 * lists for each output: the name, default trigger, and whether the signal 70 * lists for each output: the name, default trigger, and whether the signal
71 * is being used as a GPiO rather than an led. 'struct led_plaform_data' 71 * is being used as a GPiO rather than an led. 'struct led_plaform_data'
72 * is used for this. If 'name' is NULL, the output isn't used. If 'flags' 72 * is used for this. If 'name' is NULL, the output isn't used. If 'flags'
73 * is TCA6507_MAKE_CPIO, the output is a GPO. 73 * is TCA6507_MAKE_CPIO, the output is a GPO.
74 * The "struct led_platform_data" can be embedded in a 74 * The "struct led_platform_data" can be embedded in a
75 * "struct tca6507_platform_data" which adds a 'gpio_base' for the GPiOs, 75 * "struct tca6507_platform_data" which adds a 'gpio_base' for the GPiOs,
76 * and a 'setup' callback which is called once the GPiOs are available. 76 * and a 'setup' callback which is called once the GPiOs are available.
77 * 77 *
78 */ 78 */
79 79
80 #include <linux/module.h> 80 #include <linux/module.h>
81 #include <linux/slab.h> 81 #include <linux/slab.h>
82 #include <linux/leds.h> 82 #include <linux/leds.h>
83 #include <linux/err.h> 83 #include <linux/err.h>
84 #include <linux/i2c.h> 84 #include <linux/i2c.h>
85 #include <linux/gpio.h> 85 #include <linux/gpio.h>
86 #include <linux/workqueue.h> 86 #include <linux/workqueue.h>
87 #include <linux/leds-tca6507.h> 87 #include <linux/leds-tca6507.h>
88 #include <linux/of.h> 88 #include <linux/of.h>
89 89
90 /* LED select registers determine the source that drives LED outputs */ 90 /* LED select registers determine the source that drives LED outputs */
91 #define TCA6507_LS_LED_OFF 0x0 /* Output HI-Z (off) */ 91 #define TCA6507_LS_LED_OFF 0x0 /* Output HI-Z (off) */
92 #define TCA6507_LS_LED_OFF1 0x1 /* Output HI-Z (off) - not used */ 92 #define TCA6507_LS_LED_OFF1 0x1 /* Output HI-Z (off) - not used */
93 #define TCA6507_LS_LED_PWM0 0x2 /* Output LOW with Bank0 rate */ 93 #define TCA6507_LS_LED_PWM0 0x2 /* Output LOW with Bank0 rate */
94 #define TCA6507_LS_LED_PWM1 0x3 /* Output LOW with Bank1 rate */ 94 #define TCA6507_LS_LED_PWM1 0x3 /* Output LOW with Bank1 rate */
95 #define TCA6507_LS_LED_ON 0x4 /* Output LOW (on) */ 95 #define TCA6507_LS_LED_ON 0x4 /* Output LOW (on) */
96 #define TCA6507_LS_LED_MIR 0x5 /* Output LOW with Master Intensity */ 96 #define TCA6507_LS_LED_MIR 0x5 /* Output LOW with Master Intensity */
97 #define TCA6507_LS_BLINK0 0x6 /* Blink at Bank0 rate */ 97 #define TCA6507_LS_BLINK0 0x6 /* Blink at Bank0 rate */
98 #define TCA6507_LS_BLINK1 0x7 /* Blink at Bank1 rate */ 98 #define TCA6507_LS_BLINK1 0x7 /* Blink at Bank1 rate */
99 99
100 enum { 100 enum {
101 BANK0, 101 BANK0,
102 BANK1, 102 BANK1,
103 MASTER, 103 MASTER,
104 }; 104 };
105 static int bank_source[3] = { 105 static int bank_source[3] = {
106 TCA6507_LS_LED_PWM0, 106 TCA6507_LS_LED_PWM0,
107 TCA6507_LS_LED_PWM1, 107 TCA6507_LS_LED_PWM1,
108 TCA6507_LS_LED_MIR, 108 TCA6507_LS_LED_MIR,
109 }; 109 };
110 static int blink_source[2] = { 110 static int blink_source[2] = {
111 TCA6507_LS_BLINK0, 111 TCA6507_LS_BLINK0,
112 TCA6507_LS_BLINK1, 112 TCA6507_LS_BLINK1,
113 }; 113 };
114 114
115 /* PWM registers */ 115 /* PWM registers */
116 #define TCA6507_REG_CNT 11 116 #define TCA6507_REG_CNT 11
117 117
118 /* 118 /*
119 * 0x00, 0x01, 0x02 encode the TCA6507_LS_* values, each output 119 * 0x00, 0x01, 0x02 encode the TCA6507_LS_* values, each output
120 * owns one bit in each register 120 * owns one bit in each register
121 */ 121 */
122 #define TCA6507_FADE_ON 0x03 122 #define TCA6507_FADE_ON 0x03
123 #define TCA6507_FULL_ON 0x04 123 #define TCA6507_FULL_ON 0x04
124 #define TCA6507_FADE_OFF 0x05 124 #define TCA6507_FADE_OFF 0x05
125 #define TCA6507_FIRST_OFF 0x06 125 #define TCA6507_FIRST_OFF 0x06
126 #define TCA6507_SECOND_OFF 0x07 126 #define TCA6507_SECOND_OFF 0x07
127 #define TCA6507_MAX_INTENSITY 0x08 127 #define TCA6507_MAX_INTENSITY 0x08
128 #define TCA6507_MASTER_INTENSITY 0x09 128 #define TCA6507_MASTER_INTENSITY 0x09
129 #define TCA6507_INITIALIZE 0x0A 129 #define TCA6507_INITIALIZE 0x0A
130 130
131 #define INIT_CODE 0x8 131 #define INIT_CODE 0x8
132 132
133 #define TIMECODES 16 133 #define TIMECODES 16
134 static int time_codes[TIMECODES] = { 134 static int time_codes[TIMECODES] = {
135 0, 64, 128, 192, 256, 384, 512, 768, 135 0, 64, 128, 192, 256, 384, 512, 768,
136 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320 136 1024, 1536, 2048, 3072, 4096, 5760, 8128, 16320
137 }; 137 };
138 138
139 /* Convert an led.brightness level (0..255) to a TCA6507 level (0..15) */ 139 /* Convert an led.brightness level (0..255) to a TCA6507 level (0..15) */
140 static inline int TO_LEVEL(int brightness) 140 static inline int TO_LEVEL(int brightness)
141 { 141 {
142 return brightness >> 4; 142 return brightness >> 4;
143 } 143 }
144 144
145 /* ...and convert back */ 145 /* ...and convert back */
146 static inline int TO_BRIGHT(int level) 146 static inline int TO_BRIGHT(int level)
147 { 147 {
148 if (level) 148 if (level)
149 return (level << 4) | 0xf; 149 return (level << 4) | 0xf;
150 return 0; 150 return 0;
151 } 151 }
152 152
153 #define NUM_LEDS 7 153 #define NUM_LEDS 7
154 struct tca6507_chip { 154 struct tca6507_chip {
155 int reg_set; /* One bit per register where 155 int reg_set; /* One bit per register where
156 * a '1' means the register 156 * a '1' means the register
157 * should be written */ 157 * should be written */
158 u8 reg_file[TCA6507_REG_CNT]; 158 u8 reg_file[TCA6507_REG_CNT];
159 /* Bank 2 is Master Intensity and doesn't use times */ 159 /* Bank 2 is Master Intensity and doesn't use times */
160 struct bank { 160 struct bank {
161 int level; 161 int level;
162 int ontime, offtime; 162 int ontime, offtime;
163 int on_dflt, off_dflt; 163 int on_dflt, off_dflt;
164 int time_use, level_use; 164 int time_use, level_use;
165 } bank[3]; 165 } bank[3];
166 struct i2c_client *client; 166 struct i2c_client *client;
167 struct work_struct work; 167 struct work_struct work;
168 spinlock_t lock; 168 spinlock_t lock;
169 169
170 struct tca6507_led { 170 struct tca6507_led {
171 struct tca6507_chip *chip; 171 struct tca6507_chip *chip;
172 struct led_classdev led_cdev; 172 struct led_classdev led_cdev;
173 int num; 173 int num;
174 int ontime, offtime; 174 int ontime, offtime;
175 int on_dflt, off_dflt; 175 int on_dflt, off_dflt;
176 int bank; /* Bank used, or -1 */ 176 int bank; /* Bank used, or -1 */
177 int blink; /* Set if hardware-blinking */ 177 int blink; /* Set if hardware-blinking */
178 } leds[NUM_LEDS]; 178 } leds[NUM_LEDS];
179 #ifdef CONFIG_GPIOLIB 179 #ifdef CONFIG_GPIOLIB
180 struct gpio_chip gpio; 180 struct gpio_chip gpio;
181 const char *gpio_name[NUM_LEDS]; 181 const char *gpio_name[NUM_LEDS];
182 int gpio_map[NUM_LEDS]; 182 int gpio_map[NUM_LEDS];
183 #endif 183 #endif
184 }; 184 };
185 185
186 static const struct i2c_device_id tca6507_id[] = { 186 static const struct i2c_device_id tca6507_id[] = {
187 { "tca6507" }, 187 { "tca6507" },
188 { } 188 { }
189 }; 189 };
190 MODULE_DEVICE_TABLE(i2c, tca6507_id); 190 MODULE_DEVICE_TABLE(i2c, tca6507_id);
191 191
192 static int choose_times(int msec, int *c1p, int *c2p) 192 static int choose_times(int msec, int *c1p, int *c2p)
193 { 193 {
194 /* 194 /*
195 * Choose two timecodes which add to 'msec' as near as possible. 195 * Choose two timecodes which add to 'msec' as near as possible.
196 * The first returned is the 'on' or 'off' time. The second is to be 196 * The first returned is the 'on' or 'off' time. The second is to be
197 * used as a 'fade-on' or 'fade-off' time. If 'msec' is even, 197 * used as a 'fade-on' or 'fade-off' time. If 'msec' is even,
198 * the first will not be smaller than the second. If 'msec' is odd, 198 * the first will not be smaller than the second. If 'msec' is odd,
199 * the first will not be larger than the second. 199 * the first will not be larger than the second.
200 * If we cannot get a sum within 1/8 of 'msec' fail with -EINVAL, 200 * If we cannot get a sum within 1/8 of 'msec' fail with -EINVAL,
201 * otherwise return the sum that was achieved, plus 1 if the first is 201 * otherwise return the sum that was achieved, plus 1 if the first is
202 * smaller. 202 * smaller.
203 * If two possibilities are equally good (e.g. 512+0, 256+256), choose 203 * If two possibilities are equally good (e.g. 512+0, 256+256), choose
204 * the first pair so there is more change-time visible (i.e. it is 204 * the first pair so there is more change-time visible (i.e. it is
205 * softer). 205 * softer).
206 */ 206 */
207 int c1, c2; 207 int c1, c2;
208 int tmax = msec * 9 / 8; 208 int tmax = msec * 9 / 8;
209 int tmin = msec * 7 / 8; 209 int tmin = msec * 7 / 8;
210 int diff = 65536; 210 int diff = 65536;
211 211
212 /* We start at '1' to ensure we never even think of choosing a 212 /* We start at '1' to ensure we never even think of choosing a
213 * total time of '0'. 213 * total time of '0'.
214 */ 214 */
215 for (c1 = 1; c1 < TIMECODES; c1++) { 215 for (c1 = 1; c1 < TIMECODES; c1++) {
216 int t = time_codes[c1]; 216 int t = time_codes[c1];
217 if (t*2 < tmin) 217 if (t*2 < tmin)
218 continue; 218 continue;
219 if (t > tmax) 219 if (t > tmax)
220 break; 220 break;
221 for (c2 = 0; c2 <= c1; c2++) { 221 for (c2 = 0; c2 <= c1; c2++) {
222 int tt = t + time_codes[c2]; 222 int tt = t + time_codes[c2];
223 int d; 223 int d;
224 if (tt < tmin) 224 if (tt < tmin)
225 continue; 225 continue;
226 if (tt > tmax) 226 if (tt > tmax)
227 break; 227 break;
228 /* This works! */ 228 /* This works! */
229 d = abs(msec - tt); 229 d = abs(msec - tt);
230 if (d >= diff) 230 if (d >= diff)
231 continue; 231 continue;
232 /* Best yet */ 232 /* Best yet */
233 *c1p = c1; 233 *c1p = c1;
234 *c2p = c2; 234 *c2p = c2;
235 diff = d; 235 diff = d;
236 if (d == 0) 236 if (d == 0)
237 return msec; 237 return msec;
238 } 238 }
239 } 239 }
240 if (diff < 65536) { 240 if (diff < 65536) {
241 int actual; 241 int actual;
242 if (msec & 1) { 242 if (msec & 1) {
243 c1 = *c2p; 243 c1 = *c2p;
244 *c2p = *c1p; 244 *c2p = *c1p;
245 *c1p = c1; 245 *c1p = c1;
246 } 246 }
247 actual = time_codes[*c1p] + time_codes[*c2p]; 247 actual = time_codes[*c1p] + time_codes[*c2p];
248 if (*c1p < *c2p) 248 if (*c1p < *c2p)
249 return actual + 1; 249 return actual + 1;
250 else 250 else
251 return actual; 251 return actual;
252 } 252 }
253 /* No close match */ 253 /* No close match */
254 return -EINVAL; 254 return -EINVAL;
255 } 255 }
256 256
257 /* 257 /*
258 * Update the register file with the appropriate 3-bit state for 258 * Update the register file with the appropriate 3-bit state for
259 * the given led. 259 * the given led.
260 */ 260 */
261 static void set_select(struct tca6507_chip *tca, int led, int val) 261 static void set_select(struct tca6507_chip *tca, int led, int val)
262 { 262 {
263 int mask = (1 << led); 263 int mask = (1 << led);
264 int bit; 264 int bit;
265 265
266 for (bit = 0; bit < 3; bit++) { 266 for (bit = 0; bit < 3; bit++) {
267 int n = tca->reg_file[bit] & ~mask; 267 int n = tca->reg_file[bit] & ~mask;
268 if (val & (1 << bit)) 268 if (val & (1 << bit))
269 n |= mask; 269 n |= mask;
270 if (tca->reg_file[bit] != n) { 270 if (tca->reg_file[bit] != n) {
271 tca->reg_file[bit] = n; 271 tca->reg_file[bit] = n;
272 tca->reg_set |= (1 << bit); 272 tca->reg_set |= (1 << bit);
273 } 273 }
274 } 274 }
275 } 275 }
276 276
277 /* Update the register file with the appropriate 4-bit code for 277 /* Update the register file with the appropriate 4-bit code for
278 * one bank or other. This can be used for timers, for levels, or 278 * one bank or other. This can be used for timers, for levels, or
279 * for initialisation. 279 * for initialisation.
280 */ 280 */
281 static void set_code(struct tca6507_chip *tca, int reg, int bank, int new) 281 static void set_code(struct tca6507_chip *tca, int reg, int bank, int new)
282 { 282 {
283 int mask = 0xF; 283 int mask = 0xF;
284 int n; 284 int n;
285 if (bank) { 285 if (bank) {
286 mask <<= 4; 286 mask <<= 4;
287 new <<= 4; 287 new <<= 4;
288 } 288 }
289 n = tca->reg_file[reg] & ~mask; 289 n = tca->reg_file[reg] & ~mask;
290 n |= new; 290 n |= new;
291 if (tca->reg_file[reg] != n) { 291 if (tca->reg_file[reg] != n) {
292 tca->reg_file[reg] = n; 292 tca->reg_file[reg] = n;
293 tca->reg_set |= 1 << reg; 293 tca->reg_set |= 1 << reg;
294 } 294 }
295 } 295 }
296 296
297 /* Update brightness level. */ 297 /* Update brightness level. */
298 static void set_level(struct tca6507_chip *tca, int bank, int level) 298 static void set_level(struct tca6507_chip *tca, int bank, int level)
299 { 299 {
300 switch (bank) { 300 switch (bank) {
301 case BANK0: 301 case BANK0:
302 case BANK1: 302 case BANK1:
303 set_code(tca, TCA6507_MAX_INTENSITY, bank, level); 303 set_code(tca, TCA6507_MAX_INTENSITY, bank, level);
304 break; 304 break;
305 case MASTER: 305 case MASTER:
306 set_code(tca, TCA6507_MASTER_INTENSITY, 0, level); 306 set_code(tca, TCA6507_MASTER_INTENSITY, 0, level);
307 break; 307 break;
308 } 308 }
309 tca->bank[bank].level = level; 309 tca->bank[bank].level = level;
310 } 310 }
311 311
312 /* Record all relevant time code for a given bank */ 312 /* Record all relevant time code for a given bank */
313 static void set_times(struct tca6507_chip *tca, int bank) 313 static void set_times(struct tca6507_chip *tca, int bank)
314 { 314 {
315 int c1, c2; 315 int c1, c2;
316 int result; 316 int result;
317 317
318 result = choose_times(tca->bank[bank].ontime, &c1, &c2); 318 result = choose_times(tca->bank[bank].ontime, &c1, &c2);
319 dev_dbg(&tca->client->dev, 319 dev_dbg(&tca->client->dev,
320 "Chose on times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1], 320 "Chose on times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
321 c2, time_codes[c2], tca->bank[bank].ontime); 321 c2, time_codes[c2], tca->bank[bank].ontime);
322 set_code(tca, TCA6507_FADE_ON, bank, c2); 322 set_code(tca, TCA6507_FADE_ON, bank, c2);
323 set_code(tca, TCA6507_FULL_ON, bank, c1); 323 set_code(tca, TCA6507_FULL_ON, bank, c1);
324 tca->bank[bank].ontime = result; 324 tca->bank[bank].ontime = result;
325 325
326 result = choose_times(tca->bank[bank].offtime, &c1, &c2); 326 result = choose_times(tca->bank[bank].offtime, &c1, &c2);
327 dev_dbg(&tca->client->dev, 327 dev_dbg(&tca->client->dev,
328 "Chose off times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1], 328 "Chose off times %d(%d) %d(%d) for %dms\n", c1, time_codes[c1],
329 c2, time_codes[c2], tca->bank[bank].offtime); 329 c2, time_codes[c2], tca->bank[bank].offtime);
330 set_code(tca, TCA6507_FADE_OFF, bank, c2); 330 set_code(tca, TCA6507_FADE_OFF, bank, c2);
331 set_code(tca, TCA6507_FIRST_OFF, bank, c1); 331 set_code(tca, TCA6507_FIRST_OFF, bank, c1);
332 set_code(tca, TCA6507_SECOND_OFF, bank, c1); 332 set_code(tca, TCA6507_SECOND_OFF, bank, c1);
333 tca->bank[bank].offtime = result; 333 tca->bank[bank].offtime = result;
334 334
335 set_code(tca, TCA6507_INITIALIZE, bank, INIT_CODE); 335 set_code(tca, TCA6507_INITIALIZE, bank, INIT_CODE);
336 } 336 }
337 337
338 /* Write all needed register of tca6507 */ 338 /* Write all needed register of tca6507 */
339 339
340 static void tca6507_work(struct work_struct *work) 340 static void tca6507_work(struct work_struct *work)
341 { 341 {
342 struct tca6507_chip *tca = container_of(work, struct tca6507_chip, 342 struct tca6507_chip *tca = container_of(work, struct tca6507_chip,
343 work); 343 work);
344 struct i2c_client *cl = tca->client; 344 struct i2c_client *cl = tca->client;
345 int set; 345 int set;
346 u8 file[TCA6507_REG_CNT]; 346 u8 file[TCA6507_REG_CNT];
347 int r; 347 int r;
348 348
349 spin_lock_irq(&tca->lock); 349 spin_lock_irq(&tca->lock);
350 set = tca->reg_set; 350 set = tca->reg_set;
351 memcpy(file, tca->reg_file, TCA6507_REG_CNT); 351 memcpy(file, tca->reg_file, TCA6507_REG_CNT);
352 tca->reg_set = 0; 352 tca->reg_set = 0;
353 spin_unlock_irq(&tca->lock); 353 spin_unlock_irq(&tca->lock);
354 354
355 for (r = 0; r < TCA6507_REG_CNT; r++) 355 for (r = 0; r < TCA6507_REG_CNT; r++)
356 if (set & (1<<r)) 356 if (set & (1<<r))
357 i2c_smbus_write_byte_data(cl, r, file[r]); 357 i2c_smbus_write_byte_data(cl, r, file[r]);
358 } 358 }
359 359
360 static void led_release(struct tca6507_led *led) 360 static void led_release(struct tca6507_led *led)
361 { 361 {
362 /* If led owns any resource, release it. */ 362 /* If led owns any resource, release it. */
363 struct tca6507_chip *tca = led->chip; 363 struct tca6507_chip *tca = led->chip;
364 if (led->bank >= 0) { 364 if (led->bank >= 0) {
365 struct bank *b = tca->bank + led->bank; 365 struct bank *b = tca->bank + led->bank;
366 if (led->blink) 366 if (led->blink)
367 b->time_use--; 367 b->time_use--;
368 b->level_use--; 368 b->level_use--;
369 } 369 }
370 led->blink = 0; 370 led->blink = 0;
371 led->bank = -1; 371 led->bank = -1;
372 } 372 }
373 373
374 static int led_prepare(struct tca6507_led *led) 374 static int led_prepare(struct tca6507_led *led)
375 { 375 {
376 /* Assign this led to a bank, configuring that bank if necessary. */ 376 /* Assign this led to a bank, configuring that bank if necessary. */
377 int level = TO_LEVEL(led->led_cdev.brightness); 377 int level = TO_LEVEL(led->led_cdev.brightness);
378 struct tca6507_chip *tca = led->chip; 378 struct tca6507_chip *tca = led->chip;
379 int c1, c2; 379 int c1, c2;
380 int i; 380 int i;
381 struct bank *b; 381 struct bank *b;
382 int need_init = 0; 382 int need_init = 0;
383 383
384 led->led_cdev.brightness = TO_BRIGHT(level); 384 led->led_cdev.brightness = TO_BRIGHT(level);
385 if (level == 0) { 385 if (level == 0) {
386 set_select(tca, led->num, TCA6507_LS_LED_OFF); 386 set_select(tca, led->num, TCA6507_LS_LED_OFF);
387 return 0; 387 return 0;
388 } 388 }
389 389
390 if (led->ontime == 0 || led->offtime == 0) { 390 if (led->ontime == 0 || led->offtime == 0) {
391 /* 391 /*
392 * Just set the brightness, choosing first usable bank. 392 * Just set the brightness, choosing first usable bank.
393 * If none perfect, choose best. 393 * If none perfect, choose best.
394 * Count backwards so we check MASTER bank first 394 * Count backwards so we check MASTER bank first
395 * to avoid wasting a timer. 395 * to avoid wasting a timer.
396 */ 396 */
397 int best = -1;/* full-on */ 397 int best = -1;/* full-on */
398 int diff = 15-level; 398 int diff = 15-level;
399 399
400 if (level == 15) { 400 if (level == 15) {
401 set_select(tca, led->num, TCA6507_LS_LED_ON); 401 set_select(tca, led->num, TCA6507_LS_LED_ON);
402 return 0; 402 return 0;
403 } 403 }
404 404
405 for (i = MASTER; i >= BANK0; i--) { 405 for (i = MASTER; i >= BANK0; i--) {
406 int d; 406 int d;
407 if (tca->bank[i].level == level || 407 if (tca->bank[i].level == level ||
408 tca->bank[i].level_use == 0) { 408 tca->bank[i].level_use == 0) {
409 best = i; 409 best = i;
410 break; 410 break;
411 } 411 }
412 d = abs(level - tca->bank[i].level); 412 d = abs(level - tca->bank[i].level);
413 if (d < diff) { 413 if (d < diff) {
414 diff = d; 414 diff = d;
415 best = i; 415 best = i;
416 } 416 }
417 } 417 }
418 if (best == -1) { 418 if (best == -1) {
419 /* Best brightness is full-on */ 419 /* Best brightness is full-on */
420 set_select(tca, led->num, TCA6507_LS_LED_ON); 420 set_select(tca, led->num, TCA6507_LS_LED_ON);
421 led->led_cdev.brightness = LED_FULL; 421 led->led_cdev.brightness = LED_FULL;
422 return 0; 422 return 0;
423 } 423 }
424 424
425 if (!tca->bank[best].level_use) 425 if (!tca->bank[best].level_use)
426 set_level(tca, best, level); 426 set_level(tca, best, level);
427 427
428 tca->bank[best].level_use++; 428 tca->bank[best].level_use++;
429 led->bank = best; 429 led->bank = best;
430 set_select(tca, led->num, bank_source[best]); 430 set_select(tca, led->num, bank_source[best]);
431 led->led_cdev.brightness = TO_BRIGHT(tca->bank[best].level); 431 led->led_cdev.brightness = TO_BRIGHT(tca->bank[best].level);
432 return 0; 432 return 0;
433 } 433 }
434 434
435 /* 435 /*
436 * We have on/off time so we need to try to allocate a timing bank. 436 * We have on/off time so we need to try to allocate a timing bank.
437 * First check if times are compatible with hardware and give up if 437 * First check if times are compatible with hardware and give up if
438 * not. 438 * not.
439 */ 439 */
440 if (choose_times(led->ontime, &c1, &c2) < 0) 440 if (choose_times(led->ontime, &c1, &c2) < 0)
441 return -EINVAL; 441 return -EINVAL;
442 if (choose_times(led->offtime, &c1, &c2) < 0) 442 if (choose_times(led->offtime, &c1, &c2) < 0)
443 return -EINVAL; 443 return -EINVAL;
444 444
445 for (i = BANK0; i <= BANK1; i++) { 445 for (i = BANK0; i <= BANK1; i++) {
446 if (tca->bank[i].level_use == 0) 446 if (tca->bank[i].level_use == 0)
447 /* not in use - it is ours! */ 447 /* not in use - it is ours! */
448 break; 448 break;
449 if (tca->bank[i].level != level) 449 if (tca->bank[i].level != level)
450 /* Incompatible level - skip */ 450 /* Incompatible level - skip */
451 /* FIX: if timer matches we maybe should consider 451 /* FIX: if timer matches we maybe should consider
452 * this anyway... 452 * this anyway...
453 */ 453 */
454 continue; 454 continue;
455 455
456 if (tca->bank[i].time_use == 0) 456 if (tca->bank[i].time_use == 0)
457 /* Timer not in use, and level matches - use it */ 457 /* Timer not in use, and level matches - use it */
458 break; 458 break;
459 459
460 if (!(tca->bank[i].on_dflt || 460 if (!(tca->bank[i].on_dflt ||
461 led->on_dflt || 461 led->on_dflt ||
462 tca->bank[i].ontime == led->ontime)) 462 tca->bank[i].ontime == led->ontime))
463 /* on time is incompatible */ 463 /* on time is incompatible */
464 continue; 464 continue;
465 465
466 if (!(tca->bank[i].off_dflt || 466 if (!(tca->bank[i].off_dflt ||
467 led->off_dflt || 467 led->off_dflt ||
468 tca->bank[i].offtime == led->offtime)) 468 tca->bank[i].offtime == led->offtime))
469 /* off time is incompatible */ 469 /* off time is incompatible */
470 continue; 470 continue;
471 471
472 /* looks like a suitable match */ 472 /* looks like a suitable match */
473 break; 473 break;
474 } 474 }
475 475
476 if (i > BANK1) 476 if (i > BANK1)
477 /* Nothing matches - how sad */ 477 /* Nothing matches - how sad */
478 return -EINVAL; 478 return -EINVAL;
479 479
480 b = &tca->bank[i]; 480 b = &tca->bank[i];
481 if (b->level_use == 0) 481 if (b->level_use == 0)
482 set_level(tca, i, level); 482 set_level(tca, i, level);
483 b->level_use++; 483 b->level_use++;
484 led->bank = i; 484 led->bank = i;
485 485
486 if (b->on_dflt || 486 if (b->on_dflt ||
487 !led->on_dflt || 487 !led->on_dflt ||
488 b->time_use == 0) { 488 b->time_use == 0) {
489 b->ontime = led->ontime; 489 b->ontime = led->ontime;
490 b->on_dflt = led->on_dflt; 490 b->on_dflt = led->on_dflt;
491 need_init = 1; 491 need_init = 1;
492 } 492 }
493 493
494 if (b->off_dflt || 494 if (b->off_dflt ||
495 !led->off_dflt || 495 !led->off_dflt ||
496 b->time_use == 0) { 496 b->time_use == 0) {
497 b->offtime = led->offtime; 497 b->offtime = led->offtime;
498 b->off_dflt = led->off_dflt; 498 b->off_dflt = led->off_dflt;
499 need_init = 1; 499 need_init = 1;
500 } 500 }
501 501
502 if (need_init) 502 if (need_init)
503 set_times(tca, i); 503 set_times(tca, i);
504 504
505 led->ontime = b->ontime; 505 led->ontime = b->ontime;
506 led->offtime = b->offtime; 506 led->offtime = b->offtime;
507 507
508 b->time_use++; 508 b->time_use++;
509 led->blink = 1; 509 led->blink = 1;
510 led->led_cdev.brightness = TO_BRIGHT(b->level); 510 led->led_cdev.brightness = TO_BRIGHT(b->level);
511 set_select(tca, led->num, blink_source[i]); 511 set_select(tca, led->num, blink_source[i]);
512 return 0; 512 return 0;
513 } 513 }
514 514
515 static int led_assign(struct tca6507_led *led) 515 static int led_assign(struct tca6507_led *led)
516 { 516 {
517 struct tca6507_chip *tca = led->chip; 517 struct tca6507_chip *tca = led->chip;
518 int err; 518 int err;
519 unsigned long flags; 519 unsigned long flags;
520 520
521 spin_lock_irqsave(&tca->lock, flags); 521 spin_lock_irqsave(&tca->lock, flags);
522 led_release(led); 522 led_release(led);
523 err = led_prepare(led); 523 err = led_prepare(led);
524 if (err) { 524 if (err) {
525 /* 525 /*
526 * Can only fail on timer setup. In that case we need to 526 * Can only fail on timer setup. In that case we need to
527 * re-establish as steady level. 527 * re-establish as steady level.
528 */ 528 */
529 led->ontime = 0; 529 led->ontime = 0;
530 led->offtime = 0; 530 led->offtime = 0;
531 led_prepare(led); 531 led_prepare(led);
532 } 532 }
533 spin_unlock_irqrestore(&tca->lock, flags); 533 spin_unlock_irqrestore(&tca->lock, flags);
534 534
535 if (tca->reg_set) 535 if (tca->reg_set)
536 schedule_work(&tca->work); 536 schedule_work(&tca->work);
537 return err; 537 return err;
538 } 538 }
539 539
540 static void tca6507_brightness_set(struct led_classdev *led_cdev, 540 static void tca6507_brightness_set(struct led_classdev *led_cdev,
541 enum led_brightness brightness) 541 enum led_brightness brightness)
542 { 542 {
543 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led, 543 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led,
544 led_cdev); 544 led_cdev);
545 led->led_cdev.brightness = brightness; 545 led->led_cdev.brightness = brightness;
546 led->ontime = 0; 546 led->ontime = 0;
547 led->offtime = 0; 547 led->offtime = 0;
548 led_assign(led); 548 led_assign(led);
549 } 549 }
550 550
551 static int tca6507_blink_set(struct led_classdev *led_cdev, 551 static int tca6507_blink_set(struct led_classdev *led_cdev,
552 unsigned long *delay_on, 552 unsigned long *delay_on,
553 unsigned long *delay_off) 553 unsigned long *delay_off)
554 { 554 {
555 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led, 555 struct tca6507_led *led = container_of(led_cdev, struct tca6507_led,
556 led_cdev); 556 led_cdev);
557 557
558 if (*delay_on == 0) 558 if (*delay_on == 0)
559 led->on_dflt = 1; 559 led->on_dflt = 1;
560 else if (delay_on != &led_cdev->blink_delay_on) 560 else if (delay_on != &led_cdev->blink_delay_on)
561 led->on_dflt = 0; 561 led->on_dflt = 0;
562 led->ontime = *delay_on; 562 led->ontime = *delay_on;
563 563
564 if (*delay_off == 0) 564 if (*delay_off == 0)
565 led->off_dflt = 1; 565 led->off_dflt = 1;
566 else if (delay_off != &led_cdev->blink_delay_off) 566 else if (delay_off != &led_cdev->blink_delay_off)
567 led->off_dflt = 0; 567 led->off_dflt = 0;
568 led->offtime = *delay_off; 568 led->offtime = *delay_off;
569 569
570 if (led->ontime == 0) 570 if (led->ontime == 0)
571 led->ontime = 512; 571 led->ontime = 512;
572 if (led->offtime == 0) 572 if (led->offtime == 0)
573 led->offtime = 512; 573 led->offtime = 512;
574 574
575 if (led->led_cdev.brightness == LED_OFF) 575 if (led->led_cdev.brightness == LED_OFF)
576 led->led_cdev.brightness = LED_FULL; 576 led->led_cdev.brightness = LED_FULL;
577 if (led_assign(led) < 0) { 577 if (led_assign(led) < 0) {
578 led->ontime = 0; 578 led->ontime = 0;
579 led->offtime = 0; 579 led->offtime = 0;
580 led->led_cdev.brightness = LED_OFF; 580 led->led_cdev.brightness = LED_OFF;
581 return -EINVAL; 581 return -EINVAL;
582 } 582 }
583 *delay_on = led->ontime; 583 *delay_on = led->ontime;
584 *delay_off = led->offtime; 584 *delay_off = led->offtime;
585 return 0; 585 return 0;
586 } 586 }
587 587
588 #ifdef CONFIG_GPIOLIB 588 #ifdef CONFIG_GPIOLIB
589 static void tca6507_gpio_set_value(struct gpio_chip *gc, 589 static void tca6507_gpio_set_value(struct gpio_chip *gc,
590 unsigned offset, int val) 590 unsigned offset, int val)
591 { 591 {
592 struct tca6507_chip *tca = container_of(gc, struct tca6507_chip, gpio); 592 struct tca6507_chip *tca = container_of(gc, struct tca6507_chip, gpio);
593 unsigned long flags; 593 unsigned long flags;
594 594
595 spin_lock_irqsave(&tca->lock, flags); 595 spin_lock_irqsave(&tca->lock, flags);
596 /* 596 /*
597 * 'OFF' is floating high, and 'ON' is pulled down, so it has the 597 * 'OFF' is floating high, and 'ON' is pulled down, so it has the
598 * inverse sense of 'val'. 598 * inverse sense of 'val'.
599 */ 599 */
600 set_select(tca, tca->gpio_map[offset], 600 set_select(tca, tca->gpio_map[offset],
601 val ? TCA6507_LS_LED_OFF : TCA6507_LS_LED_ON); 601 val ? TCA6507_LS_LED_OFF : TCA6507_LS_LED_ON);
602 spin_unlock_irqrestore(&tca->lock, flags); 602 spin_unlock_irqrestore(&tca->lock, flags);
603 if (tca->reg_set) 603 if (tca->reg_set)
604 schedule_work(&tca->work); 604 schedule_work(&tca->work);
605 } 605 }
606 606
607 static int tca6507_gpio_direction_output(struct gpio_chip *gc, 607 static int tca6507_gpio_direction_output(struct gpio_chip *gc,
608 unsigned offset, int val) 608 unsigned offset, int val)
609 { 609 {
610 tca6507_gpio_set_value(gc, offset, val); 610 tca6507_gpio_set_value(gc, offset, val);
611 return 0; 611 return 0;
612 } 612 }
613 613
614 static int tca6507_probe_gpios(struct i2c_client *client, 614 static int tca6507_probe_gpios(struct i2c_client *client,
615 struct tca6507_chip *tca, 615 struct tca6507_chip *tca,
616 struct tca6507_platform_data *pdata) 616 struct tca6507_platform_data *pdata)
617 { 617 {
618 int err; 618 int err;
619 int i = 0; 619 int i = 0;
620 int gpios = 0; 620 int gpios = 0;
621 621
622 for (i = 0; i < NUM_LEDS; i++) 622 for (i = 0; i < NUM_LEDS; i++)
623 if (pdata->leds.leds[i].name && pdata->leds.leds[i].flags) { 623 if (pdata->leds.leds[i].name && pdata->leds.leds[i].flags) {
624 /* Configure as a gpio */ 624 /* Configure as a gpio */
625 tca->gpio_name[gpios] = pdata->leds.leds[i].name; 625 tca->gpio_name[gpios] = pdata->leds.leds[i].name;
626 tca->gpio_map[gpios] = i; 626 tca->gpio_map[gpios] = i;
627 gpios++; 627 gpios++;
628 } 628 }
629 629
630 if (!gpios) 630 if (!gpios)
631 return 0; 631 return 0;
632 632
633 tca->gpio.label = "gpio-tca6507"; 633 tca->gpio.label = "gpio-tca6507";
634 tca->gpio.names = tca->gpio_name; 634 tca->gpio.names = tca->gpio_name;
635 tca->gpio.ngpio = gpios; 635 tca->gpio.ngpio = gpios;
636 tca->gpio.base = pdata->gpio_base; 636 tca->gpio.base = pdata->gpio_base;
637 tca->gpio.owner = THIS_MODULE; 637 tca->gpio.owner = THIS_MODULE;
638 tca->gpio.direction_output = tca6507_gpio_direction_output; 638 tca->gpio.direction_output = tca6507_gpio_direction_output;
639 tca->gpio.set = tca6507_gpio_set_value; 639 tca->gpio.set = tca6507_gpio_set_value;
640 tca->gpio.dev = &client->dev; 640 tca->gpio.dev = &client->dev;
641 err = gpiochip_add(&tca->gpio); 641 err = gpiochip_add(&tca->gpio);
642 if (err) { 642 if (err) {
643 tca->gpio.ngpio = 0; 643 tca->gpio.ngpio = 0;
644 return err; 644 return err;
645 } 645 }
646 if (pdata->setup) 646 if (pdata->setup)
647 pdata->setup(tca->gpio.base, tca->gpio.ngpio); 647 pdata->setup(tca->gpio.base, tca->gpio.ngpio);
648 return 0; 648 return 0;
649 } 649 }
650 650
651 static void tca6507_remove_gpio(struct tca6507_chip *tca) 651 static void tca6507_remove_gpio(struct tca6507_chip *tca)
652 { 652 {
653 if (tca->gpio.ngpio) { 653 if (tca->gpio.ngpio) {
654 int err = gpiochip_remove(&tca->gpio); 654 int err = gpiochip_remove(&tca->gpio);
655 dev_err(&tca->client->dev, "%s failed, %d\n", 655 dev_err(&tca->client->dev, "%s failed, %d\n",
656 "gpiochip_remove()", err); 656 "gpiochip_remove()", err);
657 } 657 }
658 } 658 }
659 #else /* CONFIG_GPIOLIB */ 659 #else /* CONFIG_GPIOLIB */
660 static int tca6507_probe_gpios(struct i2c_client *client, 660 static int tca6507_probe_gpios(struct i2c_client *client,
661 struct tca6507_chip *tca, 661 struct tca6507_chip *tca,
662 struct tca6507_platform_data *pdata) 662 struct tca6507_platform_data *pdata)
663 { 663 {
664 return 0; 664 return 0;
665 } 665 }
666 static void tca6507_remove_gpio(struct tca6507_chip *tca) 666 static void tca6507_remove_gpio(struct tca6507_chip *tca)
667 { 667 {
668 } 668 }
669 #endif /* CONFIG_GPIOLIB */ 669 #endif /* CONFIG_GPIOLIB */
670 670
671 #ifdef CONFIG_OF 671 #ifdef CONFIG_OF
672 static struct tca6507_platform_data * 672 static struct tca6507_platform_data *
673 tca6507_led_dt_init(struct i2c_client *client) 673 tca6507_led_dt_init(struct i2c_client *client)
674 { 674 {
675 struct device_node *np = client->dev.of_node, *child; 675 struct device_node *np = client->dev.of_node, *child;
676 struct tca6507_platform_data *pdata; 676 struct tca6507_platform_data *pdata;
677 struct led_info *tca_leds; 677 struct led_info *tca_leds;
678 int count; 678 int count;
679 679
680 count = of_get_child_count(np); 680 count = of_get_child_count(np);
681 if (!count || count > NUM_LEDS) 681 if (!count || count > NUM_LEDS)
682 return ERR_PTR(-ENODEV); 682 return ERR_PTR(-ENODEV);
683 683
684 tca_leds = devm_kzalloc(&client->dev, 684 tca_leds = devm_kzalloc(&client->dev,
685 sizeof(struct led_info) * count, GFP_KERNEL); 685 sizeof(struct led_info) * count, GFP_KERNEL);
686 if (!tca_leds) 686 if (!tca_leds)
687 return ERR_PTR(-ENOMEM); 687 return ERR_PTR(-ENOMEM);
688 688
689 for_each_child_of_node(np, child) { 689 for_each_child_of_node(np, child) {
690 struct led_info led; 690 struct led_info led;
691 u32 reg; 691 u32 reg;
692 int ret; 692 int ret;
693 693
694 led.name = 694 led.name =
695 of_get_property(child, "label", NULL) ? : child->name; 695 of_get_property(child, "label", NULL) ? : child->name;
696 led.default_trigger = 696 led.default_trigger =
697 of_get_property(child, "linux,default-trigger", NULL); 697 of_get_property(child, "linux,default-trigger", NULL);
698 698
699 ret = of_property_read_u32(child, "reg", &reg); 699 ret = of_property_read_u32(child, "reg", &reg);
700 if (ret != 0) 700 if (ret != 0)
701 continue; 701 continue;
702 702
703 tca_leds[reg] = led; 703 tca_leds[reg] = led;
704 } 704 }
705 pdata = devm_kzalloc(&client->dev, 705 pdata = devm_kzalloc(&client->dev,
706 sizeof(struct tca6507_platform_data), GFP_KERNEL); 706 sizeof(struct tca6507_platform_data), GFP_KERNEL);
707 if (!pdata) 707 if (!pdata)
708 return ERR_PTR(-ENOMEM); 708 return ERR_PTR(-ENOMEM);
709 709
710 pdata->leds.leds = tca_leds; 710 pdata->leds.leds = tca_leds;
711 pdata->leds.num_leds = count; 711 pdata->leds.num_leds = count;
712 712
713 return pdata; 713 return pdata;
714 } 714 }
715 715
716 static const struct of_device_id of_tca6507_leds_match[] = { 716 static const struct of_device_id of_tca6507_leds_match[] = {
717 { .compatible = "ti,tca6507", }, 717 { .compatible = "ti,tca6507", },
718 {}, 718 {},
719 }; 719 };
720 720
721 #else 721 #else
722 static struct tca6507_platform_data * 722 static struct tca6507_platform_data *
723 tca6507_led_dt_init(struct i2c_client *client) 723 tca6507_led_dt_init(struct i2c_client *client)
724 { 724 {
725 return ERR_PTR(-ENODEV); 725 return ERR_PTR(-ENODEV);
726 } 726 }
727 727
728 #endif 728 #endif
729 729
730 static int tca6507_probe(struct i2c_client *client, 730 static int tca6507_probe(struct i2c_client *client,
731 const struct i2c_device_id *id) 731 const struct i2c_device_id *id)
732 { 732 {
733 struct tca6507_chip *tca; 733 struct tca6507_chip *tca;
734 struct i2c_adapter *adapter; 734 struct i2c_adapter *adapter;
735 struct tca6507_platform_data *pdata; 735 struct tca6507_platform_data *pdata;
736 int err; 736 int err;
737 int i = 0; 737 int i = 0;
738 738
739 adapter = to_i2c_adapter(client->dev.parent); 739 adapter = to_i2c_adapter(client->dev.parent);
740 pdata = client->dev.platform_data; 740 pdata = dev_get_platdata(&client->dev);
741 741
742 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) 742 if (!i2c_check_functionality(adapter, I2C_FUNC_I2C))
743 return -EIO; 743 return -EIO;
744 744
745 if (!pdata || pdata->leds.num_leds != NUM_LEDS) { 745 if (!pdata || pdata->leds.num_leds != NUM_LEDS) {
746 pdata = tca6507_led_dt_init(client); 746 pdata = tca6507_led_dt_init(client);
747 if (IS_ERR(pdata)) { 747 if (IS_ERR(pdata)) {
748 dev_err(&client->dev, "Need %d entries in platform-data list\n", 748 dev_err(&client->dev, "Need %d entries in platform-data list\n",
749 NUM_LEDS); 749 NUM_LEDS);
750 return PTR_ERR(pdata); 750 return PTR_ERR(pdata);
751 } 751 }
752 } 752 }
753 tca = devm_kzalloc(&client->dev, sizeof(*tca), GFP_KERNEL); 753 tca = devm_kzalloc(&client->dev, sizeof(*tca), GFP_KERNEL);
754 if (!tca) 754 if (!tca)
755 return -ENOMEM; 755 return -ENOMEM;
756 756
757 tca->client = client; 757 tca->client = client;
758 INIT_WORK(&tca->work, tca6507_work); 758 INIT_WORK(&tca->work, tca6507_work);
759 spin_lock_init(&tca->lock); 759 spin_lock_init(&tca->lock);
760 i2c_set_clientdata(client, tca); 760 i2c_set_clientdata(client, tca);
761 761
762 for (i = 0; i < NUM_LEDS; i++) { 762 for (i = 0; i < NUM_LEDS; i++) {
763 struct tca6507_led *l = tca->leds + i; 763 struct tca6507_led *l = tca->leds + i;
764 764
765 l->chip = tca; 765 l->chip = tca;
766 l->num = i; 766 l->num = i;
767 if (pdata->leds.leds[i].name && !pdata->leds.leds[i].flags) { 767 if (pdata->leds.leds[i].name && !pdata->leds.leds[i].flags) {
768 l->led_cdev.name = pdata->leds.leds[i].name; 768 l->led_cdev.name = pdata->leds.leds[i].name;
769 l->led_cdev.default_trigger 769 l->led_cdev.default_trigger
770 = pdata->leds.leds[i].default_trigger; 770 = pdata->leds.leds[i].default_trigger;
771 l->led_cdev.brightness_set = tca6507_brightness_set; 771 l->led_cdev.brightness_set = tca6507_brightness_set;
772 l->led_cdev.blink_set = tca6507_blink_set; 772 l->led_cdev.blink_set = tca6507_blink_set;
773 l->bank = -1; 773 l->bank = -1;
774 err = led_classdev_register(&client->dev, 774 err = led_classdev_register(&client->dev,
775 &l->led_cdev); 775 &l->led_cdev);
776 if (err < 0) 776 if (err < 0)
777 goto exit; 777 goto exit;
778 } 778 }
779 } 779 }
780 err = tca6507_probe_gpios(client, tca, pdata); 780 err = tca6507_probe_gpios(client, tca, pdata);
781 if (err) 781 if (err)
782 goto exit; 782 goto exit;
783 /* set all registers to known state - zero */ 783 /* set all registers to known state - zero */
784 tca->reg_set = 0x7f; 784 tca->reg_set = 0x7f;
785 schedule_work(&tca->work); 785 schedule_work(&tca->work);
786 786
787 return 0; 787 return 0;
788 exit: 788 exit:
789 while (i--) { 789 while (i--) {
790 if (tca->leds[i].led_cdev.name) 790 if (tca->leds[i].led_cdev.name)
791 led_classdev_unregister(&tca->leds[i].led_cdev); 791 led_classdev_unregister(&tca->leds[i].led_cdev);
792 } 792 }
793 return err; 793 return err;
794 } 794 }
795 795
796 static int tca6507_remove(struct i2c_client *client) 796 static int tca6507_remove(struct i2c_client *client)
797 { 797 {
798 int i; 798 int i;
799 struct tca6507_chip *tca = i2c_get_clientdata(client); 799 struct tca6507_chip *tca = i2c_get_clientdata(client);
800 struct tca6507_led *tca_leds = tca->leds; 800 struct tca6507_led *tca_leds = tca->leds;
801 801
802 for (i = 0; i < NUM_LEDS; i++) { 802 for (i = 0; i < NUM_LEDS; i++) {
803 if (tca_leds[i].led_cdev.name) 803 if (tca_leds[i].led_cdev.name)
804 led_classdev_unregister(&tca_leds[i].led_cdev); 804 led_classdev_unregister(&tca_leds[i].led_cdev);
805 } 805 }
806 tca6507_remove_gpio(tca); 806 tca6507_remove_gpio(tca);
807 cancel_work_sync(&tca->work); 807 cancel_work_sync(&tca->work);
808 808
809 return 0; 809 return 0;
810 } 810 }
811 811
812 static struct i2c_driver tca6507_driver = { 812 static struct i2c_driver tca6507_driver = {
813 .driver = { 813 .driver = {
814 .name = "leds-tca6507", 814 .name = "leds-tca6507",
815 .owner = THIS_MODULE, 815 .owner = THIS_MODULE,
816 .of_match_table = of_match_ptr(of_tca6507_leds_match), 816 .of_match_table = of_match_ptr(of_tca6507_leds_match),
817 }, 817 },
818 .probe = tca6507_probe, 818 .probe = tca6507_probe,
819 .remove = tca6507_remove, 819 .remove = tca6507_remove,
820 .id_table = tca6507_id, 820 .id_table = tca6507_id,
821 }; 821 };
822 822
823 module_i2c_driver(tca6507_driver); 823 module_i2c_driver(tca6507_driver);
824 824
825 MODULE_AUTHOR("NeilBrown <neilb@suse.de>"); 825 MODULE_AUTHOR("NeilBrown <neilb@suse.de>");
826 MODULE_DESCRIPTION("TCA6507 LED/GPO driver"); 826 MODULE_DESCRIPTION("TCA6507 LED/GPO driver");
827 MODULE_LICENSE("GPL v2"); 827 MODULE_LICENSE("GPL v2");
828 828
drivers/leds/leds-wm831x-status.c
1 /* 1 /*
2 * LED driver for WM831x status LEDs 2 * LED driver for WM831x status LEDs
3 * 3 *
4 * Copyright(C) 2009 Wolfson Microelectronics PLC. 4 * Copyright(C) 2009 Wolfson Microelectronics PLC.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 */ 10 */
11 11
12 #include <linux/kernel.h> 12 #include <linux/kernel.h>
13 #include <linux/init.h> 13 #include <linux/init.h>
14 #include <linux/platform_device.h> 14 #include <linux/platform_device.h>
15 #include <linux/slab.h> 15 #include <linux/slab.h>
16 #include <linux/leds.h> 16 #include <linux/leds.h>
17 #include <linux/err.h> 17 #include <linux/err.h>
18 #include <linux/mfd/wm831x/core.h> 18 #include <linux/mfd/wm831x/core.h>
19 #include <linux/mfd/wm831x/pdata.h> 19 #include <linux/mfd/wm831x/pdata.h>
20 #include <linux/mfd/wm831x/status.h> 20 #include <linux/mfd/wm831x/status.h>
21 #include <linux/module.h> 21 #include <linux/module.h>
22 22
23 23
24 struct wm831x_status { 24 struct wm831x_status {
25 struct led_classdev cdev; 25 struct led_classdev cdev;
26 struct wm831x *wm831x; 26 struct wm831x *wm831x;
27 struct work_struct work; 27 struct work_struct work;
28 struct mutex mutex; 28 struct mutex mutex;
29 29
30 spinlock_t value_lock; 30 spinlock_t value_lock;
31 int reg; /* Control register */ 31 int reg; /* Control register */
32 int reg_val; /* Control register value */ 32 int reg_val; /* Control register value */
33 33
34 int blink; 34 int blink;
35 int blink_time; 35 int blink_time;
36 int blink_cyc; 36 int blink_cyc;
37 int src; 37 int src;
38 enum led_brightness brightness; 38 enum led_brightness brightness;
39 }; 39 };
40 40
41 #define to_wm831x_status(led_cdev) \ 41 #define to_wm831x_status(led_cdev) \
42 container_of(led_cdev, struct wm831x_status, cdev) 42 container_of(led_cdev, struct wm831x_status, cdev)
43 43
44 static void wm831x_status_work(struct work_struct *work) 44 static void wm831x_status_work(struct work_struct *work)
45 { 45 {
46 struct wm831x_status *led = container_of(work, struct wm831x_status, 46 struct wm831x_status *led = container_of(work, struct wm831x_status,
47 work); 47 work);
48 unsigned long flags; 48 unsigned long flags;
49 49
50 mutex_lock(&led->mutex); 50 mutex_lock(&led->mutex);
51 51
52 led->reg_val &= ~(WM831X_LED_SRC_MASK | WM831X_LED_MODE_MASK | 52 led->reg_val &= ~(WM831X_LED_SRC_MASK | WM831X_LED_MODE_MASK |
53 WM831X_LED_DUTY_CYC_MASK | WM831X_LED_DUR_MASK); 53 WM831X_LED_DUTY_CYC_MASK | WM831X_LED_DUR_MASK);
54 54
55 spin_lock_irqsave(&led->value_lock, flags); 55 spin_lock_irqsave(&led->value_lock, flags);
56 56
57 led->reg_val |= led->src << WM831X_LED_SRC_SHIFT; 57 led->reg_val |= led->src << WM831X_LED_SRC_SHIFT;
58 if (led->blink) { 58 if (led->blink) {
59 led->reg_val |= 2 << WM831X_LED_MODE_SHIFT; 59 led->reg_val |= 2 << WM831X_LED_MODE_SHIFT;
60 led->reg_val |= led->blink_time << WM831X_LED_DUR_SHIFT; 60 led->reg_val |= led->blink_time << WM831X_LED_DUR_SHIFT;
61 led->reg_val |= led->blink_cyc; 61 led->reg_val |= led->blink_cyc;
62 } else { 62 } else {
63 if (led->brightness != LED_OFF) 63 if (led->brightness != LED_OFF)
64 led->reg_val |= 1 << WM831X_LED_MODE_SHIFT; 64 led->reg_val |= 1 << WM831X_LED_MODE_SHIFT;
65 } 65 }
66 66
67 spin_unlock_irqrestore(&led->value_lock, flags); 67 spin_unlock_irqrestore(&led->value_lock, flags);
68 68
69 wm831x_reg_write(led->wm831x, led->reg, led->reg_val); 69 wm831x_reg_write(led->wm831x, led->reg, led->reg_val);
70 70
71 mutex_unlock(&led->mutex); 71 mutex_unlock(&led->mutex);
72 } 72 }
73 73
74 static void wm831x_status_set(struct led_classdev *led_cdev, 74 static void wm831x_status_set(struct led_classdev *led_cdev,
75 enum led_brightness value) 75 enum led_brightness value)
76 { 76 {
77 struct wm831x_status *led = to_wm831x_status(led_cdev); 77 struct wm831x_status *led = to_wm831x_status(led_cdev);
78 unsigned long flags; 78 unsigned long flags;
79 79
80 spin_lock_irqsave(&led->value_lock, flags); 80 spin_lock_irqsave(&led->value_lock, flags);
81 led->brightness = value; 81 led->brightness = value;
82 if (value == LED_OFF) 82 if (value == LED_OFF)
83 led->blink = 0; 83 led->blink = 0;
84 schedule_work(&led->work); 84 schedule_work(&led->work);
85 spin_unlock_irqrestore(&led->value_lock, flags); 85 spin_unlock_irqrestore(&led->value_lock, flags);
86 } 86 }
87 87
88 static int wm831x_status_blink_set(struct led_classdev *led_cdev, 88 static int wm831x_status_blink_set(struct led_classdev *led_cdev,
89 unsigned long *delay_on, 89 unsigned long *delay_on,
90 unsigned long *delay_off) 90 unsigned long *delay_off)
91 { 91 {
92 struct wm831x_status *led = to_wm831x_status(led_cdev); 92 struct wm831x_status *led = to_wm831x_status(led_cdev);
93 unsigned long flags; 93 unsigned long flags;
94 int ret = 0; 94 int ret = 0;
95 95
96 /* Pick some defaults if we've not been given times */ 96 /* Pick some defaults if we've not been given times */
97 if (*delay_on == 0 && *delay_off == 0) { 97 if (*delay_on == 0 && *delay_off == 0) {
98 *delay_on = 250; 98 *delay_on = 250;
99 *delay_off = 250; 99 *delay_off = 250;
100 } 100 }
101 101
102 spin_lock_irqsave(&led->value_lock, flags); 102 spin_lock_irqsave(&led->value_lock, flags);
103 103
104 /* We only have a limited selection of settings, see if we can 104 /* We only have a limited selection of settings, see if we can
105 * support the configuration we're being given */ 105 * support the configuration we're being given */
106 switch (*delay_on) { 106 switch (*delay_on) {
107 case 1000: 107 case 1000:
108 led->blink_time = 0; 108 led->blink_time = 0;
109 break; 109 break;
110 case 250: 110 case 250:
111 led->blink_time = 1; 111 led->blink_time = 1;
112 break; 112 break;
113 case 125: 113 case 125:
114 led->blink_time = 2; 114 led->blink_time = 2;
115 break; 115 break;
116 case 62: 116 case 62:
117 case 63: 117 case 63:
118 /* Actually 62.5ms */ 118 /* Actually 62.5ms */
119 led->blink_time = 3; 119 led->blink_time = 3;
120 break; 120 break;
121 default: 121 default:
122 ret = -EINVAL; 122 ret = -EINVAL;
123 break; 123 break;
124 } 124 }
125 125
126 if (ret == 0) { 126 if (ret == 0) {
127 switch (*delay_off / *delay_on) { 127 switch (*delay_off / *delay_on) {
128 case 1: 128 case 1:
129 led->blink_cyc = 0; 129 led->blink_cyc = 0;
130 break; 130 break;
131 case 3: 131 case 3:
132 led->blink_cyc = 1; 132 led->blink_cyc = 1;
133 break; 133 break;
134 case 4: 134 case 4:
135 led->blink_cyc = 2; 135 led->blink_cyc = 2;
136 break; 136 break;
137 case 8: 137 case 8:
138 led->blink_cyc = 3; 138 led->blink_cyc = 3;
139 break; 139 break;
140 default: 140 default:
141 ret = -EINVAL; 141 ret = -EINVAL;
142 break; 142 break;
143 } 143 }
144 } 144 }
145 145
146 if (ret == 0) 146 if (ret == 0)
147 led->blink = 1; 147 led->blink = 1;
148 else 148 else
149 led->blink = 0; 149 led->blink = 0;
150 150
151 /* Always update; if we fail turn off blinking since we expect 151 /* Always update; if we fail turn off blinking since we expect
152 * a software fallback. */ 152 * a software fallback. */
153 schedule_work(&led->work); 153 schedule_work(&led->work);
154 154
155 spin_unlock_irqrestore(&led->value_lock, flags); 155 spin_unlock_irqrestore(&led->value_lock, flags);
156 156
157 return ret; 157 return ret;
158 } 158 }
159 159
160 static const char * const led_src_texts[] = { 160 static const char * const led_src_texts[] = {
161 "otp", 161 "otp",
162 "power", 162 "power",
163 "charger", 163 "charger",
164 "soft", 164 "soft",
165 }; 165 };
166 166
167 static ssize_t wm831x_status_src_show(struct device *dev, 167 static ssize_t wm831x_status_src_show(struct device *dev,
168 struct device_attribute *attr, char *buf) 168 struct device_attribute *attr, char *buf)
169 { 169 {
170 struct led_classdev *led_cdev = dev_get_drvdata(dev); 170 struct led_classdev *led_cdev = dev_get_drvdata(dev);
171 struct wm831x_status *led = to_wm831x_status(led_cdev); 171 struct wm831x_status *led = to_wm831x_status(led_cdev);
172 int i; 172 int i;
173 ssize_t ret = 0; 173 ssize_t ret = 0;
174 174
175 mutex_lock(&led->mutex); 175 mutex_lock(&led->mutex);
176 176
177 for (i = 0; i < ARRAY_SIZE(led_src_texts); i++) 177 for (i = 0; i < ARRAY_SIZE(led_src_texts); i++)
178 if (i == led->src) 178 if (i == led->src)
179 ret += sprintf(&buf[ret], "[%s] ", led_src_texts[i]); 179 ret += sprintf(&buf[ret], "[%s] ", led_src_texts[i]);
180 else 180 else
181 ret += sprintf(&buf[ret], "%s ", led_src_texts[i]); 181 ret += sprintf(&buf[ret], "%s ", led_src_texts[i]);
182 182
183 mutex_unlock(&led->mutex); 183 mutex_unlock(&led->mutex);
184 184
185 ret += sprintf(&buf[ret], "\n"); 185 ret += sprintf(&buf[ret], "\n");
186 186
187 return ret; 187 return ret;
188 } 188 }
189 189
190 static ssize_t wm831x_status_src_store(struct device *dev, 190 static ssize_t wm831x_status_src_store(struct device *dev,
191 struct device_attribute *attr, 191 struct device_attribute *attr,
192 const char *buf, size_t size) 192 const char *buf, size_t size)
193 { 193 {
194 struct led_classdev *led_cdev = dev_get_drvdata(dev); 194 struct led_classdev *led_cdev = dev_get_drvdata(dev);
195 struct wm831x_status *led = to_wm831x_status(led_cdev); 195 struct wm831x_status *led = to_wm831x_status(led_cdev);
196 char name[20]; 196 char name[20];
197 int i; 197 int i;
198 size_t len; 198 size_t len;
199 199
200 name[sizeof(name) - 1] = '\0'; 200 name[sizeof(name) - 1] = '\0';
201 strncpy(name, buf, sizeof(name) - 1); 201 strncpy(name, buf, sizeof(name) - 1);
202 len = strlen(name); 202 len = strlen(name);
203 203
204 if (len && name[len - 1] == '\n') 204 if (len && name[len - 1] == '\n')
205 name[len - 1] = '\0'; 205 name[len - 1] = '\0';
206 206
207 for (i = 0; i < ARRAY_SIZE(led_src_texts); i++) { 207 for (i = 0; i < ARRAY_SIZE(led_src_texts); i++) {
208 if (!strcmp(name, led_src_texts[i])) { 208 if (!strcmp(name, led_src_texts[i])) {
209 mutex_lock(&led->mutex); 209 mutex_lock(&led->mutex);
210 210
211 led->src = i; 211 led->src = i;
212 schedule_work(&led->work); 212 schedule_work(&led->work);
213 213
214 mutex_unlock(&led->mutex); 214 mutex_unlock(&led->mutex);
215 } 215 }
216 } 216 }
217 217
218 return size; 218 return size;
219 } 219 }
220 220
221 static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store); 221 static DEVICE_ATTR(src, 0644, wm831x_status_src_show, wm831x_status_src_store);
222 222
223 static int wm831x_status_probe(struct platform_device *pdev) 223 static int wm831x_status_probe(struct platform_device *pdev)
224 { 224 {
225 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); 225 struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
226 struct wm831x_pdata *chip_pdata; 226 struct wm831x_pdata *chip_pdata;
227 struct wm831x_status_pdata pdata; 227 struct wm831x_status_pdata pdata;
228 struct wm831x_status *drvdata; 228 struct wm831x_status *drvdata;
229 struct resource *res; 229 struct resource *res;
230 int id = pdev->id % ARRAY_SIZE(chip_pdata->status); 230 int id = pdev->id % ARRAY_SIZE(chip_pdata->status);
231 int ret; 231 int ret;
232 232
233 res = platform_get_resource(pdev, IORESOURCE_IO, 0); 233 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
234 if (res == NULL) { 234 if (res == NULL) {
235 dev_err(&pdev->dev, "No I/O resource\n"); 235 dev_err(&pdev->dev, "No I/O resource\n");
236 ret = -EINVAL; 236 ret = -EINVAL;
237 goto err; 237 goto err;
238 } 238 }
239 239
240 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status), 240 drvdata = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_status),
241 GFP_KERNEL); 241 GFP_KERNEL);
242 if (!drvdata) 242 if (!drvdata)
243 return -ENOMEM; 243 return -ENOMEM;
244 platform_set_drvdata(pdev, drvdata); 244 platform_set_drvdata(pdev, drvdata);
245 245
246 drvdata->wm831x = wm831x; 246 drvdata->wm831x = wm831x;
247 drvdata->reg = res->start; 247 drvdata->reg = res->start;
248 248
249 if (wm831x->dev->platform_data) 249 if (dev_get_platdata(wm831x->dev))
250 chip_pdata = wm831x->dev->platform_data; 250 chip_pdata = dev_get_platdata(wm831x->dev);
251 else 251 else
252 chip_pdata = NULL; 252 chip_pdata = NULL;
253 253
254 memset(&pdata, 0, sizeof(pdata)); 254 memset(&pdata, 0, sizeof(pdata));
255 if (chip_pdata && chip_pdata->status[id]) 255 if (chip_pdata && chip_pdata->status[id])
256 memcpy(&pdata, chip_pdata->status[id], sizeof(pdata)); 256 memcpy(&pdata, chip_pdata->status[id], sizeof(pdata));
257 else 257 else
258 pdata.name = dev_name(&pdev->dev); 258 pdata.name = dev_name(&pdev->dev);
259 259
260 mutex_init(&drvdata->mutex); 260 mutex_init(&drvdata->mutex);
261 INIT_WORK(&drvdata->work, wm831x_status_work); 261 INIT_WORK(&drvdata->work, wm831x_status_work);
262 spin_lock_init(&drvdata->value_lock); 262 spin_lock_init(&drvdata->value_lock);
263 263
264 /* We cache the configuration register and read startup values 264 /* We cache the configuration register and read startup values
265 * from it. */ 265 * from it. */
266 drvdata->reg_val = wm831x_reg_read(wm831x, drvdata->reg); 266 drvdata->reg_val = wm831x_reg_read(wm831x, drvdata->reg);
267 267
268 if (drvdata->reg_val & WM831X_LED_MODE_MASK) 268 if (drvdata->reg_val & WM831X_LED_MODE_MASK)
269 drvdata->brightness = LED_FULL; 269 drvdata->brightness = LED_FULL;
270 else 270 else
271 drvdata->brightness = LED_OFF; 271 drvdata->brightness = LED_OFF;
272 272
273 /* Set a default source if configured, otherwise leave the 273 /* Set a default source if configured, otherwise leave the
274 * current hardware setting. 274 * current hardware setting.
275 */ 275 */
276 if (pdata.default_src == WM831X_STATUS_PRESERVE) { 276 if (pdata.default_src == WM831X_STATUS_PRESERVE) {
277 drvdata->src = drvdata->reg_val; 277 drvdata->src = drvdata->reg_val;
278 drvdata->src &= WM831X_LED_SRC_MASK; 278 drvdata->src &= WM831X_LED_SRC_MASK;
279 drvdata->src >>= WM831X_LED_SRC_SHIFT; 279 drvdata->src >>= WM831X_LED_SRC_SHIFT;
280 } else { 280 } else {
281 drvdata->src = pdata.default_src - 1; 281 drvdata->src = pdata.default_src - 1;
282 } 282 }
283 283
284 drvdata->cdev.name = pdata.name; 284 drvdata->cdev.name = pdata.name;
285 drvdata->cdev.default_trigger = pdata.default_trigger; 285 drvdata->cdev.default_trigger = pdata.default_trigger;
286 drvdata->cdev.brightness_set = wm831x_status_set; 286 drvdata->cdev.brightness_set = wm831x_status_set;
287 drvdata->cdev.blink_set = wm831x_status_blink_set; 287 drvdata->cdev.blink_set = wm831x_status_blink_set;
288 288
289 ret = led_classdev_register(wm831x->dev, &drvdata->cdev); 289 ret = led_classdev_register(wm831x->dev, &drvdata->cdev);
290 if (ret < 0) { 290 if (ret < 0) {
291 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret); 291 dev_err(&pdev->dev, "Failed to register LED: %d\n", ret);
292 goto err_led; 292 goto err_led;
293 } 293 }
294 294
295 ret = device_create_file(drvdata->cdev.dev, &dev_attr_src); 295 ret = device_create_file(drvdata->cdev.dev, &dev_attr_src);
296 if (ret != 0) 296 if (ret != 0)
297 dev_err(&pdev->dev, 297 dev_err(&pdev->dev,
298 "No source control for LED: %d\n", ret); 298 "No source control for LED: %d\n", ret);
299 299
300 return 0; 300 return 0;
301 301
302 err_led: 302 err_led:
303 led_classdev_unregister(&drvdata->cdev); 303 led_classdev_unregister(&drvdata->cdev);
304 err: 304 err:
305 return ret; 305 return ret;
306 } 306 }
307 307
308 static int wm831x_status_remove(struct platform_device *pdev) 308 static int wm831x_status_remove(struct platform_device *pdev)
309 { 309 {
310 struct wm831x_status *drvdata = platform_get_drvdata(pdev); 310 struct wm831x_status *drvdata = platform_get_drvdata(pdev);
311 311
312 device_remove_file(drvdata->cdev.dev, &dev_attr_src); 312 device_remove_file(drvdata->cdev.dev, &dev_attr_src);
313 led_classdev_unregister(&drvdata->cdev); 313 led_classdev_unregister(&drvdata->cdev);
314 314
315 return 0; 315 return 0;
316 } 316 }
317 317
318 static struct platform_driver wm831x_status_driver = { 318 static struct platform_driver wm831x_status_driver = {
319 .driver = { 319 .driver = {
320 .name = "wm831x-status", 320 .name = "wm831x-status",
321 .owner = THIS_MODULE, 321 .owner = THIS_MODULE,
322 }, 322 },
323 .probe = wm831x_status_probe, 323 .probe = wm831x_status_probe,
324 .remove = wm831x_status_remove, 324 .remove = wm831x_status_remove,
325 }; 325 };
326 326
327 module_platform_driver(wm831x_status_driver); 327 module_platform_driver(wm831x_status_driver);
328 328
329 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); 329 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
330 MODULE_DESCRIPTION("WM831x status LED driver"); 330 MODULE_DESCRIPTION("WM831x status LED driver");
331 MODULE_LICENSE("GPL"); 331 MODULE_LICENSE("GPL");
332 MODULE_ALIAS("platform:wm831x-status"); 332 MODULE_ALIAS("platform:wm831x-status");
333 333
drivers/leds/leds-wm8350.c
1 /* 1 /*
2 * LED driver for WM8350 driven LEDS. 2 * LED driver for WM8350 driven LEDS.
3 * 3 *
4 * Copyright(C) 2007, 2008 Wolfson Microelectronics PLC. 4 * Copyright(C) 2007, 2008 Wolfson Microelectronics PLC.
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as 7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 * 9 *
10 */ 10 */
11 11
12 #include <linux/kernel.h> 12 #include <linux/kernel.h>
13 #include <linux/init.h> 13 #include <linux/init.h>
14 #include <linux/platform_device.h> 14 #include <linux/platform_device.h>
15 #include <linux/leds.h> 15 #include <linux/leds.h>
16 #include <linux/err.h> 16 #include <linux/err.h>
17 #include <linux/mfd/wm8350/pmic.h> 17 #include <linux/mfd/wm8350/pmic.h>
18 #include <linux/regulator/consumer.h> 18 #include <linux/regulator/consumer.h>
19 #include <linux/slab.h> 19 #include <linux/slab.h>
20 #include <linux/module.h> 20 #include <linux/module.h>
21 21
22 /* Microamps */ 22 /* Microamps */
23 static const int isink_cur[] = { 23 static const int isink_cur[] = {
24 4, 24 4,
25 5, 25 5,
26 6, 26 6,
27 7, 27 7,
28 8, 28 8,
29 10, 29 10,
30 11, 30 11,
31 14, 31 14,
32 16, 32 16,
33 19, 33 19,
34 23, 34 23,
35 27, 35 27,
36 32, 36 32,
37 39, 37 39,
38 46, 38 46,
39 54, 39 54,
40 65, 40 65,
41 77, 41 77,
42 92, 42 92,
43 109, 43 109,
44 130, 44 130,
45 154, 45 154,
46 183, 46 183,
47 218, 47 218,
48 259, 48 259,
49 308, 49 308,
50 367, 50 367,
51 436, 51 436,
52 518, 52 518,
53 616, 53 616,
54 733, 54 733,
55 872, 55 872,
56 1037, 56 1037,
57 1233, 57 1233,
58 1466, 58 1466,
59 1744, 59 1744,
60 2073, 60 2073,
61 2466, 61 2466,
62 2933, 62 2933,
63 3487, 63 3487,
64 4147, 64 4147,
65 4932, 65 4932,
66 5865, 66 5865,
67 6975, 67 6975,
68 8294, 68 8294,
69 9864, 69 9864,
70 11730, 70 11730,
71 13949, 71 13949,
72 16589, 72 16589,
73 19728, 73 19728,
74 23460, 74 23460,
75 27899, 75 27899,
76 33178, 76 33178,
77 39455, 77 39455,
78 46920, 78 46920,
79 55798, 79 55798,
80 66355, 80 66355,
81 78910, 81 78910,
82 93840, 82 93840,
83 111596, 83 111596,
84 132710, 84 132710,
85 157820, 85 157820,
86 187681, 86 187681,
87 223191 87 223191
88 }; 88 };
89 89
90 #define to_wm8350_led(led_cdev) \ 90 #define to_wm8350_led(led_cdev) \
91 container_of(led_cdev, struct wm8350_led, cdev) 91 container_of(led_cdev, struct wm8350_led, cdev)
92 92
93 static void wm8350_led_enable(struct wm8350_led *led) 93 static void wm8350_led_enable(struct wm8350_led *led)
94 { 94 {
95 int ret; 95 int ret;
96 96
97 if (led->enabled) 97 if (led->enabled)
98 return; 98 return;
99 99
100 ret = regulator_enable(led->isink); 100 ret = regulator_enable(led->isink);
101 if (ret != 0) { 101 if (ret != 0) {
102 dev_err(led->cdev.dev, "Failed to enable ISINK: %d\n", ret); 102 dev_err(led->cdev.dev, "Failed to enable ISINK: %d\n", ret);
103 return; 103 return;
104 } 104 }
105 105
106 ret = regulator_enable(led->dcdc); 106 ret = regulator_enable(led->dcdc);
107 if (ret != 0) { 107 if (ret != 0) {
108 dev_err(led->cdev.dev, "Failed to enable DCDC: %d\n", ret); 108 dev_err(led->cdev.dev, "Failed to enable DCDC: %d\n", ret);
109 regulator_disable(led->isink); 109 regulator_disable(led->isink);
110 return; 110 return;
111 } 111 }
112 112
113 led->enabled = 1; 113 led->enabled = 1;
114 } 114 }
115 115
116 static void wm8350_led_disable(struct wm8350_led *led) 116 static void wm8350_led_disable(struct wm8350_led *led)
117 { 117 {
118 int ret; 118 int ret;
119 119
120 if (!led->enabled) 120 if (!led->enabled)
121 return; 121 return;
122 122
123 ret = regulator_disable(led->dcdc); 123 ret = regulator_disable(led->dcdc);
124 if (ret != 0) { 124 if (ret != 0) {
125 dev_err(led->cdev.dev, "Failed to disable DCDC: %d\n", ret); 125 dev_err(led->cdev.dev, "Failed to disable DCDC: %d\n", ret);
126 return; 126 return;
127 } 127 }
128 128
129 ret = regulator_disable(led->isink); 129 ret = regulator_disable(led->isink);
130 if (ret != 0) { 130 if (ret != 0) {
131 dev_err(led->cdev.dev, "Failed to disable ISINK: %d\n", ret); 131 dev_err(led->cdev.dev, "Failed to disable ISINK: %d\n", ret);
132 ret = regulator_enable(led->dcdc); 132 ret = regulator_enable(led->dcdc);
133 if (ret != 0) 133 if (ret != 0)
134 dev_err(led->cdev.dev, "Failed to reenable DCDC: %d\n", 134 dev_err(led->cdev.dev, "Failed to reenable DCDC: %d\n",
135 ret); 135 ret);
136 return; 136 return;
137 } 137 }
138 138
139 led->enabled = 0; 139 led->enabled = 0;
140 } 140 }
141 141
142 static void led_work(struct work_struct *work) 142 static void led_work(struct work_struct *work)
143 { 143 {
144 struct wm8350_led *led = container_of(work, struct wm8350_led, work); 144 struct wm8350_led *led = container_of(work, struct wm8350_led, work);
145 int ret; 145 int ret;
146 int uA; 146 int uA;
147 unsigned long flags; 147 unsigned long flags;
148 148
149 mutex_lock(&led->mutex); 149 mutex_lock(&led->mutex);
150 150
151 spin_lock_irqsave(&led->value_lock, flags); 151 spin_lock_irqsave(&led->value_lock, flags);
152 152
153 if (led->value == LED_OFF) { 153 if (led->value == LED_OFF) {
154 spin_unlock_irqrestore(&led->value_lock, flags); 154 spin_unlock_irqrestore(&led->value_lock, flags);
155 wm8350_led_disable(led); 155 wm8350_led_disable(led);
156 goto out; 156 goto out;
157 } 157 }
158 158
159 /* This scales linearly into the index of valid current 159 /* This scales linearly into the index of valid current
160 * settings which results in a linear scaling of perceived 160 * settings which results in a linear scaling of perceived
161 * brightness due to the non-linear current settings provided 161 * brightness due to the non-linear current settings provided
162 * by the hardware. 162 * by the hardware.
163 */ 163 */
164 uA = (led->max_uA_index * led->value) / LED_FULL; 164 uA = (led->max_uA_index * led->value) / LED_FULL;
165 spin_unlock_irqrestore(&led->value_lock, flags); 165 spin_unlock_irqrestore(&led->value_lock, flags);
166 BUG_ON(uA >= ARRAY_SIZE(isink_cur)); 166 BUG_ON(uA >= ARRAY_SIZE(isink_cur));
167 167
168 ret = regulator_set_current_limit(led->isink, isink_cur[uA], 168 ret = regulator_set_current_limit(led->isink, isink_cur[uA],
169 isink_cur[uA]); 169 isink_cur[uA]);
170 if (ret != 0) 170 if (ret != 0)
171 dev_err(led->cdev.dev, "Failed to set %duA: %d\n", 171 dev_err(led->cdev.dev, "Failed to set %duA: %d\n",
172 isink_cur[uA], ret); 172 isink_cur[uA], ret);
173 173
174 wm8350_led_enable(led); 174 wm8350_led_enable(led);
175 175
176 out: 176 out:
177 mutex_unlock(&led->mutex); 177 mutex_unlock(&led->mutex);
178 } 178 }
179 179
180 static void wm8350_led_set(struct led_classdev *led_cdev, 180 static void wm8350_led_set(struct led_classdev *led_cdev,
181 enum led_brightness value) 181 enum led_brightness value)
182 { 182 {
183 struct wm8350_led *led = to_wm8350_led(led_cdev); 183 struct wm8350_led *led = to_wm8350_led(led_cdev);
184 unsigned long flags; 184 unsigned long flags;
185 185
186 spin_lock_irqsave(&led->value_lock, flags); 186 spin_lock_irqsave(&led->value_lock, flags);
187 led->value = value; 187 led->value = value;
188 schedule_work(&led->work); 188 schedule_work(&led->work);
189 spin_unlock_irqrestore(&led->value_lock, flags); 189 spin_unlock_irqrestore(&led->value_lock, flags);
190 } 190 }
191 191
192 static void wm8350_led_shutdown(struct platform_device *pdev) 192 static void wm8350_led_shutdown(struct platform_device *pdev)
193 { 193 {
194 struct wm8350_led *led = platform_get_drvdata(pdev); 194 struct wm8350_led *led = platform_get_drvdata(pdev);
195 195
196 mutex_lock(&led->mutex); 196 mutex_lock(&led->mutex);
197 led->value = LED_OFF; 197 led->value = LED_OFF;
198 wm8350_led_disable(led); 198 wm8350_led_disable(led);
199 mutex_unlock(&led->mutex); 199 mutex_unlock(&led->mutex);
200 } 200 }
201 201
202 static int wm8350_led_probe(struct platform_device *pdev) 202 static int wm8350_led_probe(struct platform_device *pdev)
203 { 203 {
204 struct regulator *isink, *dcdc; 204 struct regulator *isink, *dcdc;
205 struct wm8350_led *led; 205 struct wm8350_led *led;
206 struct wm8350_led_platform_data *pdata = pdev->dev.platform_data; 206 struct wm8350_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
207 int i; 207 int i;
208 208
209 if (pdata == NULL) { 209 if (pdata == NULL) {
210 dev_err(&pdev->dev, "no platform data\n"); 210 dev_err(&pdev->dev, "no platform data\n");
211 return -ENODEV; 211 return -ENODEV;
212 } 212 }
213 213
214 if (pdata->max_uA < isink_cur[0]) { 214 if (pdata->max_uA < isink_cur[0]) {
215 dev_err(&pdev->dev, "Invalid maximum current %duA\n", 215 dev_err(&pdev->dev, "Invalid maximum current %duA\n",
216 pdata->max_uA); 216 pdata->max_uA);
217 return -EINVAL; 217 return -EINVAL;
218 } 218 }
219 219
220 isink = devm_regulator_get(&pdev->dev, "led_isink"); 220 isink = devm_regulator_get(&pdev->dev, "led_isink");
221 if (IS_ERR(isink)) { 221 if (IS_ERR(isink)) {
222 dev_err(&pdev->dev, "%s: can't get ISINK\n", __func__); 222 dev_err(&pdev->dev, "%s: can't get ISINK\n", __func__);
223 return PTR_ERR(isink); 223 return PTR_ERR(isink);
224 } 224 }
225 225
226 dcdc = devm_regulator_get(&pdev->dev, "led_vcc"); 226 dcdc = devm_regulator_get(&pdev->dev, "led_vcc");
227 if (IS_ERR(dcdc)) { 227 if (IS_ERR(dcdc)) {
228 dev_err(&pdev->dev, "%s: can't get DCDC\n", __func__); 228 dev_err(&pdev->dev, "%s: can't get DCDC\n", __func__);
229 return PTR_ERR(dcdc); 229 return PTR_ERR(dcdc);
230 } 230 }
231 231
232 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL); 232 led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
233 if (led == NULL) 233 if (led == NULL)
234 return -ENOMEM; 234 return -ENOMEM;
235 235
236 led->cdev.brightness_set = wm8350_led_set; 236 led->cdev.brightness_set = wm8350_led_set;
237 led->cdev.default_trigger = pdata->default_trigger; 237 led->cdev.default_trigger = pdata->default_trigger;
238 led->cdev.name = pdata->name; 238 led->cdev.name = pdata->name;
239 led->cdev.flags |= LED_CORE_SUSPENDRESUME; 239 led->cdev.flags |= LED_CORE_SUSPENDRESUME;
240 led->enabled = regulator_is_enabled(isink); 240 led->enabled = regulator_is_enabled(isink);
241 led->isink = isink; 241 led->isink = isink;
242 led->dcdc = dcdc; 242 led->dcdc = dcdc;
243 243
244 for (i = 0; i < ARRAY_SIZE(isink_cur) - 1; i++) 244 for (i = 0; i < ARRAY_SIZE(isink_cur) - 1; i++)
245 if (isink_cur[i] >= pdata->max_uA) 245 if (isink_cur[i] >= pdata->max_uA)
246 break; 246 break;
247 led->max_uA_index = i; 247 led->max_uA_index = i;
248 if (pdata->max_uA != isink_cur[i]) 248 if (pdata->max_uA != isink_cur[i])
249 dev_warn(&pdev->dev, 249 dev_warn(&pdev->dev,
250 "Maximum current %duA is not directly supported," 250 "Maximum current %duA is not directly supported,"
251 " check platform data\n", 251 " check platform data\n",
252 pdata->max_uA); 252 pdata->max_uA);
253 253
254 spin_lock_init(&led->value_lock); 254 spin_lock_init(&led->value_lock);
255 mutex_init(&led->mutex); 255 mutex_init(&led->mutex);
256 INIT_WORK(&led->work, led_work); 256 INIT_WORK(&led->work, led_work);
257 led->value = LED_OFF; 257 led->value = LED_OFF;
258 platform_set_drvdata(pdev, led); 258 platform_set_drvdata(pdev, led);
259 259
260 return led_classdev_register(&pdev->dev, &led->cdev); 260 return led_classdev_register(&pdev->dev, &led->cdev);
261 } 261 }
262 262
263 static int wm8350_led_remove(struct platform_device *pdev) 263 static int wm8350_led_remove(struct platform_device *pdev)
264 { 264 {
265 struct wm8350_led *led = platform_get_drvdata(pdev); 265 struct wm8350_led *led = platform_get_drvdata(pdev);
266 266
267 led_classdev_unregister(&led->cdev); 267 led_classdev_unregister(&led->cdev);
268 flush_work(&led->work); 268 flush_work(&led->work);
269 wm8350_led_disable(led); 269 wm8350_led_disable(led);
270 return 0; 270 return 0;
271 } 271 }
272 272
273 static struct platform_driver wm8350_led_driver = { 273 static struct platform_driver wm8350_led_driver = {
274 .driver = { 274 .driver = {
275 .name = "wm8350-led", 275 .name = "wm8350-led",
276 .owner = THIS_MODULE, 276 .owner = THIS_MODULE,
277 }, 277 },
278 .probe = wm8350_led_probe, 278 .probe = wm8350_led_probe,
279 .remove = wm8350_led_remove, 279 .remove = wm8350_led_remove,
280 .shutdown = wm8350_led_shutdown, 280 .shutdown = wm8350_led_shutdown,
281 }; 281 };
282 282
283 module_platform_driver(wm8350_led_driver); 283 module_platform_driver(wm8350_led_driver);
284 284
285 MODULE_AUTHOR("Mark Brown"); 285 MODULE_AUTHOR("Mark Brown");
286 MODULE_DESCRIPTION("WM8350 LED driver"); 286 MODULE_DESCRIPTION("WM8350 LED driver");
287 MODULE_LICENSE("GPL"); 287 MODULE_LICENSE("GPL");
288 MODULE_ALIAS("platform:wm8350-led"); 288 MODULE_ALIAS("platform:wm8350-led");
289 289