1 /*
2  * LP55XX Common Driver Header
3  *
4  * Copyright (C) 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
9  * modify it under the terms of the GNU General Public License
10  * version 2 as published by the Free Software Foundation.
11  *
12  * Derived from leds-lp5521.c, leds-lp5523.c
13  */
14 
15 #ifndef _LEDS_LP55XX_COMMON_H
16 #define _LEDS_LP55XX_COMMON_H
17 
18 enum lp55xx_engine_index {
19 	LP55XX_ENGINE_INVALID,
20 	LP55XX_ENGINE_1,
21 	LP55XX_ENGINE_2,
22 	LP55XX_ENGINE_3,
23 	LP55XX_ENGINE_MAX = LP55XX_ENGINE_3,
24 };
25 
26 enum lp55xx_engine_mode {
27 	LP55XX_ENGINE_DISABLED,
28 	LP55XX_ENGINE_LOAD,
29 	LP55XX_ENGINE_RUN,
30 };
31 
32 #define LP55XX_DEV_ATTR_RW(name, show, store)	\
33 	DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show, store)
34 #define LP55XX_DEV_ATTR_RO(name, show)		\
35 	DEVICE_ATTR(name, S_IRUGO, show, NULL)
36 #define LP55XX_DEV_ATTR_WO(name, store)		\
37 	DEVICE_ATTR(name, S_IWUSR, NULL, store)
38 
39 #define show_mode(nr)							\
40 static ssize_t show_engine##nr##_mode(struct device *dev,		\
41 				    struct device_attribute *attr,	\
42 				    char *buf)				\
43 {									\
44 	return show_engine_mode(dev, attr, buf, nr);			\
45 }
46 
47 #define store_mode(nr)							\
48 static ssize_t store_engine##nr##_mode(struct device *dev,		\
49 				     struct device_attribute *attr,	\
50 				     const char *buf, size_t len)	\
51 {									\
52 	return store_engine_mode(dev, attr, buf, len, nr);		\
53 }
54 
55 #define show_leds(nr)							\
56 static ssize_t show_engine##nr##_leds(struct device *dev,		\
57 			    struct device_attribute *attr,		\
58 			    char *buf)					\
59 {									\
60 	return show_engine_leds(dev, attr, buf, nr);			\
61 }
62 
63 #define store_leds(nr)						\
64 static ssize_t store_engine##nr##_leds(struct device *dev,	\
65 			     struct device_attribute *attr,	\
66 			     const char *buf, size_t len)	\
67 {								\
68 	return store_engine_leds(dev, attr, buf, len, nr);	\
69 }
70 
71 #define store_load(nr)							\
72 static ssize_t store_engine##nr##_load(struct device *dev,		\
73 				     struct device_attribute *attr,	\
74 				     const char *buf, size_t len)	\
75 {									\
76 	return store_engine_load(dev, attr, buf, len, nr);		\
77 }
78 
79 struct lp55xx_led;
80 struct lp55xx_chip;
81 
82 /*
83  * struct lp55xx_reg
84  * @addr : Register address
85  * @val  : Register value
86  */
87 struct lp55xx_reg {
88 	u8 addr;
89 	u8 val;
90 };
91 
92 /*
93  * struct lp55xx_device_config
94  * @reset              : Chip specific reset command
95  * @enable             : Chip specific enable command
96  * @max_channel        : Maximum number of channels
97  * @post_init_device   : Chip specific initialization code
98  * @brightness_fn      : Brightness function
99  * @set_led_current    : LED current set function
100  * @firmware_cb        : Call function when the firmware is loaded
101  * @run_engine         : Run internal engine for pattern
102  * @dev_attr_group     : Device specific attributes
103  */
104 struct lp55xx_device_config {
105 	const struct lp55xx_reg reset;
106 	const struct lp55xx_reg enable;
107 	const int max_channel;
108 
109 	/* define if the device has specific initialization process */
110 	int (*post_init_device) (struct lp55xx_chip *chip);
111 
112 	/* access brightness register */
113 	int (*brightness_fn)(struct lp55xx_led *led);
114 
115 	/* current setting function */
116 	void (*set_led_current) (struct lp55xx_led *led, u8 led_current);
117 
118 	/* access program memory when the firmware is loaded */
119 	void (*firmware_cb)(struct lp55xx_chip *chip);
120 
121 	/* used for running firmware LED patterns */
122 	void (*run_engine) (struct lp55xx_chip *chip, bool start);
123 
124 	/* additional device specific attributes */
125 	const struct attribute_group *dev_attr_group;
126 };
127 
128 /*
129  * struct lp55xx_engine
130  * @mode       : Engine mode
131  * @led_mux    : Mux bits for LED selection. Only used in LP5523
132  */
133 struct lp55xx_engine {
134 	enum lp55xx_engine_mode mode;
135 	u16 led_mux;
136 };
137 
138 /*
139  * struct lp55xx_chip
140  * @cl         : I2C communication for access registers
141  * @pdata      : Platform specific data
142  * @lock       : Lock for user-space interface
143  * @num_leds   : Number of registered LEDs
144  * @cfg        : Device specific configuration data
145  * @engine_idx : Selected engine number
146  * @engines    : Engine structure for the device attribute R/W interface
147  * @fw         : Firmware data for running a LED pattern
148  */
149 struct lp55xx_chip {
150 	struct i2c_client *cl;
151 	struct clk *clk;
152 	struct lp55xx_platform_data *pdata;
153 	struct mutex lock;	/* lock for user-space interface */
154 	int num_leds;
155 	struct lp55xx_device_config *cfg;
156 	enum lp55xx_engine_index engine_idx;
157 	struct lp55xx_engine engines[LP55XX_ENGINE_MAX];
158 	const struct firmware *fw;
159 };
160 
161 /*
162  * struct lp55xx_led
163  * @chan_nr         : Channel number
164  * @cdev            : LED class device
165  * @led_current     : Current setting at each led channel
166  * @max_current     : Maximun current at each led channel
167  * @brightness      : Brightness value
168  * @chip            : The lp55xx chip data
169  */
170 struct lp55xx_led {
171 	int chan_nr;
172 	struct led_classdev cdev;
173 	u8 led_current;
174 	u8 max_current;
175 	u8 brightness;
176 	struct lp55xx_chip *chip;
177 };
178 
179 /* register access */
180 extern int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val);
181 extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val);
182 extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg,
183 			u8 mask, u8 val);
184 
185 /* external clock detection */
186 extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);
187 
188 /* common device init/deinit functions */
189 extern int lp55xx_init_device(struct lp55xx_chip *chip);
190 extern void lp55xx_deinit_device(struct lp55xx_chip *chip);
191 
192 /* common LED class device functions */
193 extern int lp55xx_register_leds(struct lp55xx_led *led,
194 				struct lp55xx_chip *chip);
195 extern void lp55xx_unregister_leds(struct lp55xx_led *led,
196 				struct lp55xx_chip *chip);
197 
198 /* common device attributes functions */
199 extern int lp55xx_register_sysfs(struct lp55xx_chip *chip);
200 extern void lp55xx_unregister_sysfs(struct lp55xx_chip *chip);
201 
202 /* common device tree population function */
203 extern struct lp55xx_platform_data
204 *lp55xx_of_populate_pdata(struct device *dev, struct device_node *np);
205 
206 #endif /* _LEDS_LP55XX_COMMON_H */
207