Commit 68853bc2b360c06094477523f7d28efd2d9e3bf3

Authored by Kim, Milo
Committed by Linus Torvalds
1 parent 5eb02c01bd

backlight: lp855x_bl: introduce device configuration flow

At this moment, LP855x device driver has fixed register configuration.
For example, fixed register addresses and values are set on the device
initialization.  But new device of LP855x family, LP8557 has different
register map and initialization sequence.  To support new device
architecture, initialization process should be changed.

 Introduce new structure: lp855x_device_config
 =============================================
 With lp855x_device_config, device specific features are configurable.
 Use configurable function calls and register addresses rather than fixed values.

 Change on device initialization
 ===============================
 In old LP855x driver architecture, the device initialization was simple.
 - Just update the brightness/device control register/ROM area(optional).
 In new LP855x driver architecture, two more works are added - pre_init and
 post_init.
 Those init functions are optional, used for new device LP8557.

 New device initialization flow: generic sequence
 =================================================
 1) pre_init_device()
 2) update the brightness register
 3) update the device control register
 4) update ROM area if need
 5) post_init_device()

 Name change
 ===========
 Use generic name 'lp855x_configure()' instead of 'lp855x_init_registers()'.

Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Acked-by: Jingoo Han <jg1.han@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 1 changed file with 68 additions and 10 deletions Inline Diff

drivers/video/backlight/lp855x_bl.c
1 /* 1 /*
2 * TI LP855x Backlight Driver 2 * TI LP855x Backlight Driver
3 * 3 *
4 * Copyright (C) 2011 Texas Instruments 4 * Copyright (C) 2011 Texas Instruments
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/module.h> 12 #include <linux/module.h>
13 #include <linux/slab.h> 13 #include <linux/slab.h>
14 #include <linux/i2c.h> 14 #include <linux/i2c.h>
15 #include <linux/backlight.h> 15 #include <linux/backlight.h>
16 #include <linux/err.h> 16 #include <linux/err.h>
17 #include <linux/platform_data/lp855x.h> 17 #include <linux/platform_data/lp855x.h>
18 #include <linux/pwm.h> 18 #include <linux/pwm.h>
19 19
20 /* Registers */ 20 /* Registers */
21 #define BRIGHTNESS_CTRL 0x00 21 #define BRIGHTNESS_CTRL 0x00
22 #define DEVICE_CTRL 0x01 22 #define DEVICE_CTRL 0x01
23 #define EEPROM_START 0xA0 23 #define EEPROM_START 0xA0
24 #define EEPROM_END 0xA7 24 #define EEPROM_END 0xA7
25 #define EPROM_START 0xA0 25 #define EPROM_START 0xA0
26 #define EPROM_END 0xAF 26 #define EPROM_END 0xAF
27 27
28 #define BUF_SIZE 20 28 #define BUF_SIZE 20
29 #define DEFAULT_BL_NAME "lcd-backlight" 29 #define DEFAULT_BL_NAME "lcd-backlight"
30 #define MAX_BRIGHTNESS 255 30 #define MAX_BRIGHTNESS 255
31 31
32 struct lp855x;
33
34 /*
35 * struct lp855x_device_config
36 * @pre_init_device: init device function call before updating the brightness
37 * @reg_brightness: register address for brigthenss control
38 * @reg_devicectrl: register address for device control
39 * @post_init_device: late init device function call
40 */
41 struct lp855x_device_config {
42 int (*pre_init_device)(struct lp855x *);
43 u8 reg_brightness;
44 u8 reg_devicectrl;
45 int (*post_init_device)(struct lp855x *);
46 };
47
32 struct lp855x { 48 struct lp855x {
33 const char *chipname; 49 const char *chipname;
34 enum lp855x_chip_id chip_id; 50 enum lp855x_chip_id chip_id;
51 struct lp855x_device_config *cfg;
35 struct i2c_client *client; 52 struct i2c_client *client;
36 struct backlight_device *bl; 53 struct backlight_device *bl;
37 struct device *dev; 54 struct device *dev;
38 struct lp855x_platform_data *pdata; 55 struct lp855x_platform_data *pdata;
39 struct pwm_device *pwm; 56 struct pwm_device *pwm;
40 }; 57 };
41 58
42 static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data) 59 static int lp855x_read_byte(struct lp855x *lp, u8 reg, u8 *data)
43 { 60 {
44 int ret; 61 int ret;
45 62
46 ret = i2c_smbus_read_byte_data(lp->client, reg); 63 ret = i2c_smbus_read_byte_data(lp->client, reg);
47 if (ret < 0) { 64 if (ret < 0) {
48 dev_err(lp->dev, "failed to read 0x%.2x\n", reg); 65 dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
49 return ret; 66 return ret;
50 } 67 }
51 68
52 *data = (u8)ret; 69 *data = (u8)ret;
53 return 0; 70 return 0;
54 } 71 }
55 72
56 static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data) 73 static int lp855x_write_byte(struct lp855x *lp, u8 reg, u8 data)
57 { 74 {
58 return i2c_smbus_write_byte_data(lp->client, reg, data); 75 return i2c_smbus_write_byte_data(lp->client, reg, data);
59 } 76 }
60 77
61 static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr) 78 static bool lp855x_is_valid_rom_area(struct lp855x *lp, u8 addr)
62 { 79 {
63 u8 start, end; 80 u8 start, end;
64 81
65 switch (lp->chip_id) { 82 switch (lp->chip_id) {
66 case LP8550: 83 case LP8550:
67 case LP8551: 84 case LP8551:
68 case LP8552: 85 case LP8552:
69 case LP8553: 86 case LP8553:
70 start = EEPROM_START; 87 start = EEPROM_START;
71 end = EEPROM_END; 88 end = EEPROM_END;
72 break; 89 break;
73 case LP8556: 90 case LP8556:
74 start = EPROM_START; 91 start = EPROM_START;
75 end = EPROM_END; 92 end = EPROM_END;
76 break; 93 break;
77 default: 94 default:
78 return false; 95 return false;
79 } 96 }
80 97
81 return (addr >= start && addr <= end); 98 return (addr >= start && addr <= end);
82 } 99 }
83 100
84 static int lp855x_init_registers(struct lp855x *lp) 101 static struct lp855x_device_config lp855x_dev_cfg = {
102 .reg_brightness = BRIGHTNESS_CTRL,
103 .reg_devicectrl = DEVICE_CTRL,
104 };
105
106 /*
107 * Device specific configuration flow
108 *
109 * a) pre_init_device(optional)
110 * b) update the brightness register
111 * c) update device control register
112 * d) update ROM area(optional)
113 * e) post_init_device(optional)
114 *
115 */
116 static int lp855x_configure(struct lp855x *lp)
85 { 117 {
86 u8 val, addr; 118 u8 val, addr;
87 int i, ret; 119 int i, ret;
88 struct lp855x_platform_data *pd = lp->pdata; 120 struct lp855x_platform_data *pd = lp->pdata;
89 121
122 switch (lp->chip_id) {
123 case LP8550 ... LP8556:
124 lp->cfg = &lp855x_dev_cfg;
125 break;
126 default:
127 return -EINVAL;
128 }
129
130 if (lp->cfg->pre_init_device) {
131 ret = lp->cfg->pre_init_device(lp);
132 if (ret) {
133 dev_err(lp->dev, "pre init device err: %d\n", ret);
134 goto err;
135 }
136 }
137
90 val = pd->initial_brightness; 138 val = pd->initial_brightness;
91 ret = lp855x_write_byte(lp, BRIGHTNESS_CTRL, val); 139 ret = lp855x_write_byte(lp, lp->cfg->reg_brightness, val);
92 if (ret) 140 if (ret)
93 return ret; 141 goto err;
94 142
95 val = pd->device_control; 143 val = pd->device_control;
96 ret = lp855x_write_byte(lp, DEVICE_CTRL, val); 144 ret = lp855x_write_byte(lp, lp->cfg->reg_devicectrl, val);
97 if (ret) 145 if (ret)
98 return ret; 146 goto err;
99 147
100 if (pd->load_new_rom_data && pd->size_program) { 148 if (pd->load_new_rom_data && pd->size_program) {
101 for (i = 0; i < pd->size_program; i++) { 149 for (i = 0; i < pd->size_program; i++) {
102 addr = pd->rom_data[i].addr; 150 addr = pd->rom_data[i].addr;
103 val = pd->rom_data[i].val; 151 val = pd->rom_data[i].val;
104 if (!lp855x_is_valid_rom_area(lp, addr)) 152 if (!lp855x_is_valid_rom_area(lp, addr))
105 continue; 153 continue;
106 154
107 ret = lp855x_write_byte(lp, addr, val); 155 ret = lp855x_write_byte(lp, addr, val);
108 if (ret) 156 if (ret)
109 return ret; 157 goto err;
110 } 158 }
111 } 159 }
112 160
161 if (lp->cfg->post_init_device) {
162 ret = lp->cfg->post_init_device(lp);
163 if (ret) {
164 dev_err(lp->dev, "post init device err: %d\n", ret);
165 goto err;
166 }
167 }
168
169 return 0;
170
171 err:
113 return ret; 172 return ret;
114 } 173 }
115 174
116 static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br) 175 static void lp855x_pwm_ctrl(struct lp855x *lp, int br, int max_br)
117 { 176 {
118 unsigned int period = lp->pdata->period_ns; 177 unsigned int period = lp->pdata->period_ns;
119 unsigned int duty = br * period / max_br; 178 unsigned int duty = br * period / max_br;
120 struct pwm_device *pwm; 179 struct pwm_device *pwm;
121 180
122 /* request pwm device with the consumer name */ 181 /* request pwm device with the consumer name */
123 if (!lp->pwm) { 182 if (!lp->pwm) {
124 pwm = devm_pwm_get(lp->dev, lp->chipname); 183 pwm = devm_pwm_get(lp->dev, lp->chipname);
125 if (IS_ERR(pwm)) 184 if (IS_ERR(pwm))
126 return; 185 return;
127 186
128 lp->pwm = pwm; 187 lp->pwm = pwm;
129 } 188 }
130 189
131 pwm_config(lp->pwm, duty, period); 190 pwm_config(lp->pwm, duty, period);
132 if (duty) 191 if (duty)
133 pwm_enable(lp->pwm); 192 pwm_enable(lp->pwm);
134 else 193 else
135 pwm_disable(lp->pwm); 194 pwm_disable(lp->pwm);
136 } 195 }
137 196
138 static int lp855x_bl_update_status(struct backlight_device *bl) 197 static int lp855x_bl_update_status(struct backlight_device *bl)
139 { 198 {
140 struct lp855x *lp = bl_get_data(bl); 199 struct lp855x *lp = bl_get_data(bl);
141 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode; 200 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
142 201
143 if (bl->props.state & BL_CORE_SUSPENDED) 202 if (bl->props.state & BL_CORE_SUSPENDED)
144 bl->props.brightness = 0; 203 bl->props.brightness = 0;
145 204
146 if (mode == PWM_BASED) { 205 if (mode == PWM_BASED) {
147 int br = bl->props.brightness; 206 int br = bl->props.brightness;
148 int max_br = bl->props.max_brightness; 207 int max_br = bl->props.max_brightness;
149 208
150 lp855x_pwm_ctrl(lp, br, max_br); 209 lp855x_pwm_ctrl(lp, br, max_br);
151 210
152 } else if (mode == REGISTER_BASED) { 211 } else if (mode == REGISTER_BASED) {
153 u8 val = bl->props.brightness; 212 u8 val = bl->props.brightness;
154 lp855x_write_byte(lp, BRIGHTNESS_CTRL, val); 213 lp855x_write_byte(lp, BRIGHTNESS_CTRL, val);
155 } 214 }
156 215
157 return 0; 216 return 0;
158 } 217 }
159 218
160 static int lp855x_bl_get_brightness(struct backlight_device *bl) 219 static int lp855x_bl_get_brightness(struct backlight_device *bl)
161 { 220 {
162 struct lp855x *lp = bl_get_data(bl); 221 struct lp855x *lp = bl_get_data(bl);
163 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode; 222 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
164 223
165 if (mode == REGISTER_BASED) { 224 if (mode == REGISTER_BASED) {
166 u8 val = 0; 225 u8 val = 0;
167 226
168 lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val); 227 lp855x_read_byte(lp, BRIGHTNESS_CTRL, &val);
169 bl->props.brightness = val; 228 bl->props.brightness = val;
170 } 229 }
171 230
172 return bl->props.brightness; 231 return bl->props.brightness;
173 } 232 }
174 233
175 static const struct backlight_ops lp855x_bl_ops = { 234 static const struct backlight_ops lp855x_bl_ops = {
176 .options = BL_CORE_SUSPENDRESUME, 235 .options = BL_CORE_SUSPENDRESUME,
177 .update_status = lp855x_bl_update_status, 236 .update_status = lp855x_bl_update_status,
178 .get_brightness = lp855x_bl_get_brightness, 237 .get_brightness = lp855x_bl_get_brightness,
179 }; 238 };
180 239
181 static int lp855x_backlight_register(struct lp855x *lp) 240 static int lp855x_backlight_register(struct lp855x *lp)
182 { 241 {
183 struct backlight_device *bl; 242 struct backlight_device *bl;
184 struct backlight_properties props; 243 struct backlight_properties props;
185 struct lp855x_platform_data *pdata = lp->pdata; 244 struct lp855x_platform_data *pdata = lp->pdata;
186 char *name = pdata->name ? : DEFAULT_BL_NAME; 245 char *name = pdata->name ? : DEFAULT_BL_NAME;
187 246
188 props.type = BACKLIGHT_PLATFORM; 247 props.type = BACKLIGHT_PLATFORM;
189 props.max_brightness = MAX_BRIGHTNESS; 248 props.max_brightness = MAX_BRIGHTNESS;
190 249
191 if (pdata->initial_brightness > props.max_brightness) 250 if (pdata->initial_brightness > props.max_brightness)
192 pdata->initial_brightness = props.max_brightness; 251 pdata->initial_brightness = props.max_brightness;
193 252
194 props.brightness = pdata->initial_brightness; 253 props.brightness = pdata->initial_brightness;
195 254
196 bl = backlight_device_register(name, lp->dev, lp, 255 bl = backlight_device_register(name, lp->dev, lp,
197 &lp855x_bl_ops, &props); 256 &lp855x_bl_ops, &props);
198 if (IS_ERR(bl)) 257 if (IS_ERR(bl))
199 return PTR_ERR(bl); 258 return PTR_ERR(bl);
200 259
201 lp->bl = bl; 260 lp->bl = bl;
202 261
203 return 0; 262 return 0;
204 } 263 }
205 264
206 static void lp855x_backlight_unregister(struct lp855x *lp) 265 static void lp855x_backlight_unregister(struct lp855x *lp)
207 { 266 {
208 if (lp->bl) 267 if (lp->bl)
209 backlight_device_unregister(lp->bl); 268 backlight_device_unregister(lp->bl);
210 } 269 }
211 270
212 static ssize_t lp855x_get_chip_id(struct device *dev, 271 static ssize_t lp855x_get_chip_id(struct device *dev,
213 struct device_attribute *attr, char *buf) 272 struct device_attribute *attr, char *buf)
214 { 273 {
215 struct lp855x *lp = dev_get_drvdata(dev); 274 struct lp855x *lp = dev_get_drvdata(dev);
216 return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname); 275 return scnprintf(buf, BUF_SIZE, "%s\n", lp->chipname);
217 } 276 }
218 277
219 static ssize_t lp855x_get_bl_ctl_mode(struct device *dev, 278 static ssize_t lp855x_get_bl_ctl_mode(struct device *dev,
220 struct device_attribute *attr, char *buf) 279 struct device_attribute *attr, char *buf)
221 { 280 {
222 struct lp855x *lp = dev_get_drvdata(dev); 281 struct lp855x *lp = dev_get_drvdata(dev);
223 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode; 282 enum lp855x_brightness_ctrl_mode mode = lp->pdata->mode;
224 char *strmode = NULL; 283 char *strmode = NULL;
225 284
226 if (mode == PWM_BASED) 285 if (mode == PWM_BASED)
227 strmode = "pwm based"; 286 strmode = "pwm based";
228 else if (mode == REGISTER_BASED) 287 else if (mode == REGISTER_BASED)
229 strmode = "register based"; 288 strmode = "register based";
230 289
231 return scnprintf(buf, BUF_SIZE, "%s\n", strmode); 290 return scnprintf(buf, BUF_SIZE, "%s\n", strmode);
232 } 291 }
233 292
234 static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL); 293 static DEVICE_ATTR(chip_id, S_IRUGO, lp855x_get_chip_id, NULL);
235 static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL); 294 static DEVICE_ATTR(bl_ctl_mode, S_IRUGO, lp855x_get_bl_ctl_mode, NULL);
236 295
237 static struct attribute *lp855x_attributes[] = { 296 static struct attribute *lp855x_attributes[] = {
238 &dev_attr_chip_id.attr, 297 &dev_attr_chip_id.attr,
239 &dev_attr_bl_ctl_mode.attr, 298 &dev_attr_bl_ctl_mode.attr,
240 NULL, 299 NULL,
241 }; 300 };
242 301
243 static const struct attribute_group lp855x_attr_group = { 302 static const struct attribute_group lp855x_attr_group = {
244 .attrs = lp855x_attributes, 303 .attrs = lp855x_attributes,
245 }; 304 };
246 305
247 static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 306 static int lp855x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
248 { 307 {
249 struct lp855x *lp; 308 struct lp855x *lp;
250 struct lp855x_platform_data *pdata = cl->dev.platform_data; 309 struct lp855x_platform_data *pdata = cl->dev.platform_data;
251 enum lp855x_brightness_ctrl_mode mode; 310 enum lp855x_brightness_ctrl_mode mode;
252 int ret; 311 int ret;
253 312
254 if (!pdata) { 313 if (!pdata) {
255 dev_err(&cl->dev, "no platform data supplied\n"); 314 dev_err(&cl->dev, "no platform data supplied\n");
256 return -EINVAL; 315 return -EINVAL;
257 } 316 }
258 317
259 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) 318 if (!i2c_check_functionality(cl->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
260 return -EIO; 319 return -EIO;
261 320
262 lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL); 321 lp = devm_kzalloc(&cl->dev, sizeof(struct lp855x), GFP_KERNEL);
263 if (!lp) 322 if (!lp)
264 return -ENOMEM; 323 return -ENOMEM;
265 324
266 mode = pdata->mode; 325 mode = pdata->mode;
267 lp->client = cl; 326 lp->client = cl;
268 lp->dev = &cl->dev; 327 lp->dev = &cl->dev;
269 lp->pdata = pdata; 328 lp->pdata = pdata;
270 lp->chipname = id->name; 329 lp->chipname = id->name;
271 lp->chip_id = id->driver_data; 330 lp->chip_id = id->driver_data;
272 i2c_set_clientdata(cl, lp); 331 i2c_set_clientdata(cl, lp);
273 332
274 ret = lp855x_init_registers(lp); 333 ret = lp855x_configure(lp);
275 if (ret) { 334 if (ret) {
276 dev_err(lp->dev, "i2c communication err: %d", ret); 335 dev_err(lp->dev, "device config err: %d", ret);
277 if (mode == REGISTER_BASED) 336 goto err_dev;
278 goto err_dev;
279 } 337 }
280 338
281 ret = lp855x_backlight_register(lp); 339 ret = lp855x_backlight_register(lp);
282 if (ret) { 340 if (ret) {
283 dev_err(lp->dev, 341 dev_err(lp->dev,
284 "failed to register backlight. err: %d\n", ret); 342 "failed to register backlight. err: %d\n", ret);
285 goto err_dev; 343 goto err_dev;
286 } 344 }
287 345
288 ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group); 346 ret = sysfs_create_group(&lp->dev->kobj, &lp855x_attr_group);
289 if (ret) { 347 if (ret) {
290 dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret); 348 dev_err(lp->dev, "failed to register sysfs. err: %d\n", ret);
291 goto err_sysfs; 349 goto err_sysfs;
292 } 350 }
293 351
294 backlight_update_status(lp->bl); 352 backlight_update_status(lp->bl);
295 return 0; 353 return 0;
296 354
297 err_sysfs: 355 err_sysfs:
298 lp855x_backlight_unregister(lp); 356 lp855x_backlight_unregister(lp);
299 err_dev: 357 err_dev:
300 return ret; 358 return ret;
301 } 359 }
302 360
303 static int lp855x_remove(struct i2c_client *cl) 361 static int lp855x_remove(struct i2c_client *cl)
304 { 362 {
305 struct lp855x *lp = i2c_get_clientdata(cl); 363 struct lp855x *lp = i2c_get_clientdata(cl);
306 364
307 lp->bl->props.brightness = 0; 365 lp->bl->props.brightness = 0;
308 backlight_update_status(lp->bl); 366 backlight_update_status(lp->bl);
309 sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group); 367 sysfs_remove_group(&lp->dev->kobj, &lp855x_attr_group);
310 lp855x_backlight_unregister(lp); 368 lp855x_backlight_unregister(lp);
311 369
312 return 0; 370 return 0;
313 } 371 }
314 372
315 static const struct i2c_device_id lp855x_ids[] = { 373 static const struct i2c_device_id lp855x_ids[] = {
316 {"lp8550", LP8550}, 374 {"lp8550", LP8550},
317 {"lp8551", LP8551}, 375 {"lp8551", LP8551},
318 {"lp8552", LP8552}, 376 {"lp8552", LP8552},
319 {"lp8553", LP8553}, 377 {"lp8553", LP8553},
320 {"lp8556", LP8556}, 378 {"lp8556", LP8556},
321 { } 379 { }
322 }; 380 };
323 MODULE_DEVICE_TABLE(i2c, lp855x_ids); 381 MODULE_DEVICE_TABLE(i2c, lp855x_ids);
324 382
325 static struct i2c_driver lp855x_driver = { 383 static struct i2c_driver lp855x_driver = {
326 .driver = { 384 .driver = {
327 .name = "lp855x", 385 .name = "lp855x",
328 }, 386 },
329 .probe = lp855x_probe, 387 .probe = lp855x_probe,
330 .remove = lp855x_remove, 388 .remove = lp855x_remove,
331 .id_table = lp855x_ids, 389 .id_table = lp855x_ids,
332 }; 390 };
333 391
334 module_i2c_driver(lp855x_driver); 392 module_i2c_driver(lp855x_driver);
335 393
336 MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver"); 394 MODULE_DESCRIPTION("Texas Instruments LP855x Backlight driver");
337 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>"); 395 MODULE_AUTHOR("Milo Kim <milo.kim@ti.com>");
338 MODULE_LICENSE("GPL"); 396 MODULE_LICENSE("GPL");