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 --- |