leds-lp55xx-common.c (b3b6f8119d752c969c6394314dc7ab80e6611111) leds-lp55xx-common.c (10c06d178df11b0b2b746321a80ea14241997127)
1/*
2 * LP5521/LP5523/LP55231 Common Driver
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
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
10 * published by the Free Software Foundation.
11 *
12 * Derived from leds-lp5521.c, leds-lp5523.c
13 */
14
15#include <linux/delay.h>
1/*
2 * LP5521/LP5523/LP55231 Common Driver
3 *
4 * Copyright 2012 Texas Instruments
5 *
6 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
7 *
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
10 * published by the Free Software Foundation.
11 *
12 * Derived from leds-lp5521.c, leds-lp5523.c
13 */
14
15#include <linux/delay.h>
16#include <linux/firmware.h>
16#include <linux/i2c.h>
17#include <linux/leds.h>
18#include <linux/module.h>
19#include <linux/platform_data/leds-lp55xx.h>
20
21#include "leds-lp55xx-common.h"
22
23static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)

--- 168 unchanged lines hidden (view full) ---

192 dev_err(dev, "led sysfs err: %d\n", ret);
193 led_classdev_unregister(&led->cdev);
194 return ret;
195 }
196
197 return 0;
198}
199
17#include <linux/i2c.h>
18#include <linux/leds.h>
19#include <linux/module.h>
20#include <linux/platform_data/leds-lp55xx.h>
21
22#include "leds-lp55xx-common.h"
23
24static struct lp55xx_led *cdev_to_lp55xx_led(struct led_classdev *cdev)

--- 168 unchanged lines hidden (view full) ---

193 dev_err(dev, "led sysfs err: %d\n", ret);
194 led_classdev_unregister(&led->cdev);
195 return ret;
196 }
197
198 return 0;
199}
200
201static void lp55xx_firmware_loaded(const struct firmware *fw, void *context)
202{
203 struct lp55xx_chip *chip = context;
204 struct device *dev = &chip->cl->dev;
205
206 if (!fw) {
207 dev_err(dev, "firmware request failed\n");
208 goto out;
209 }
210
211 /* handling firmware data is chip dependent */
212 mutex_lock(&chip->lock);
213
214 chip->fw = fw;
215 if (chip->cfg->firmware_cb)
216 chip->cfg->firmware_cb(chip);
217
218 mutex_unlock(&chip->lock);
219
220out:
221 /* firmware should be released for other channel use */
222 release_firmware(chip->fw);
223}
224
225static int lp55xx_request_firmware(struct lp55xx_chip *chip)
226{
227 const char *name = chip->cl->name;
228 struct device *dev = &chip->cl->dev;
229
230 return request_firmware_nowait(THIS_MODULE, true, name, dev,
231 GFP_KERNEL, chip, lp55xx_firmware_loaded);
232}
233
234static ssize_t lp55xx_show_engine_select(struct device *dev,
235 struct device_attribute *attr,
236 char *buf)
237{
238 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
239 struct lp55xx_chip *chip = led->chip;
240
241 return sprintf(buf, "%d\n", chip->engine_idx);
242}
243
244static ssize_t lp55xx_store_engine_select(struct device *dev,
245 struct device_attribute *attr,
246 const char *buf, size_t len)
247{
248 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
249 struct lp55xx_chip *chip = led->chip;
250 unsigned long val;
251 int ret;
252
253 if (kstrtoul(buf, 0, &val))
254 return -EINVAL;
255
256 /* select the engine to be run */
257
258 switch (val) {
259 case LP55XX_ENGINE_1:
260 case LP55XX_ENGINE_2:
261 case LP55XX_ENGINE_3:
262 mutex_lock(&chip->lock);
263 chip->engine_idx = val;
264 ret = lp55xx_request_firmware(chip);
265 mutex_unlock(&chip->lock);
266 break;
267 default:
268 dev_err(dev, "%lu: invalid engine index. (1, 2, 3)\n", val);
269 return -EINVAL;
270 }
271
272 if (ret) {
273 dev_err(dev, "request firmware err: %d\n", ret);
274 return ret;
275 }
276
277 return len;
278}
279
280static inline void lp55xx_run_engine(struct lp55xx_chip *chip, bool start)
281{
282 if (chip->cfg->run_engine)
283 chip->cfg->run_engine(chip, start);
284}
285
286static ssize_t lp55xx_store_engine_run(struct device *dev,
287 struct device_attribute *attr,
288 const char *buf, size_t len)
289{
290 struct lp55xx_led *led = i2c_get_clientdata(to_i2c_client(dev));
291 struct lp55xx_chip *chip = led->chip;
292 unsigned long val;
293
294 if (kstrtoul(buf, 0, &val))
295 return -EINVAL;
296
297 /* run or stop the selected engine */
298
299 if (val <= 0) {
300 lp55xx_run_engine(chip, false);
301 return len;
302 }
303
304 mutex_lock(&chip->lock);
305 lp55xx_run_engine(chip, true);
306 mutex_unlock(&chip->lock);
307
308 return len;
309}
310
311static DEVICE_ATTR(select_engine, S_IRUGO | S_IWUSR,
312 lp55xx_show_engine_select, lp55xx_store_engine_select);
313static DEVICE_ATTR(run_engine, S_IWUSR, NULL, lp55xx_store_engine_run);
314
200static struct attribute *lp55xx_engine_attributes[] = {
315static struct attribute *lp55xx_engine_attributes[] = {
316 &dev_attr_select_engine.attr,
317 &dev_attr_run_engine.attr,
201 NULL,
202};
203
204static const struct attribute_group lp55xx_engine_attr_group = {
205 .attrs = lp55xx_engine_attributes,
206};
207
208int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)

--- 178 unchanged lines hidden ---
318 NULL,
319};
320
321static const struct attribute_group lp55xx_engine_attr_group = {
322 .attrs = lp55xx_engine_attributes,
323};
324
325int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val)

--- 178 unchanged lines hidden ---