summaryrefslogtreecommitdiff
path: root/drivers/leds/leds-lp55xx-common.h
blob: e638049d929795d846cce4d6d549065c83dd8217 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * LP55XX Common Driver Header
 *
 * Copyright (C) 2012 Texas Instruments
 *
 * Author: Milo(Woogyom) Kim <milo.kim@ti.com>
 *
 * Derived from leds-lp5521.c, leds-lp5523.c
 */

#ifndef _LEDS_LP55XX_COMMON_H
#define _LEDS_LP55XX_COMMON_H

#include <linux/led-class-multicolor.h>

enum lp55xx_engine_index {
	LP55XX_ENGINE_INVALID,
	LP55XX_ENGINE_1,
	LP55XX_ENGINE_2,
	LP55XX_ENGINE_3,
	LP55XX_ENGINE_MAX = LP55XX_ENGINE_3,
};

enum lp55xx_engine_mode {
	LP55XX_ENGINE_DISABLED,
	LP55XX_ENGINE_LOAD,
	LP55XX_ENGINE_RUN,
};

#define LP55XX_DEV_ATTR_RW(name, show, store)	\
	DEVICE_ATTR(name, S_IRUGO | S_IWUSR, show, store)
#define LP55XX_DEV_ATTR_RO(name, show)		\
	DEVICE_ATTR(name, S_IRUGO, show, NULL)
#define LP55XX_DEV_ATTR_WO(name, store)		\
	DEVICE_ATTR(name, S_IWUSR, NULL, store)

#define show_mode(nr)							\
static ssize_t show_engine##nr##_mode(struct device *dev,		\
				    struct device_attribute *attr,	\
				    char *buf)				\
{									\
	return show_engine_mode(dev, attr, buf, nr);			\
}

#define store_mode(nr)							\
static ssize_t store_engine##nr##_mode(struct device *dev,		\
				     struct device_attribute *attr,	\
				     const char *buf, size_t len)	\
{									\
	return store_engine_mode(dev, attr, buf, len, nr);		\
}

#define show_leds(nr)							\
static ssize_t show_engine##nr##_leds(struct device *dev,		\
			    struct device_attribute *attr,		\
			    char *buf)					\
{									\
	return show_engine_leds(dev, attr, buf, nr);			\
}

#define store_leds(nr)						\
static ssize_t store_engine##nr##_leds(struct device *dev,	\
			     struct device_attribute *attr,	\
			     const char *buf, size_t len)	\
{								\
	return store_engine_leds(dev, attr, buf, len, nr);	\
}

#define store_load(nr)							\
static ssize_t store_engine##nr##_load(struct device *dev,		\
				     struct device_attribute *attr,	\
				     const char *buf, size_t len)	\
{									\
	return store_engine_load(dev, attr, buf, len, nr);		\
}

struct lp55xx_led;
struct lp55xx_chip;

/*
 * struct lp55xx_reg
 * @addr : Register address
 * @val  : Register value (can also used as mask or shift)
 */
struct lp55xx_reg {
	u8 addr;
	union {
		u8 val;
		u8 mask;
		u8 shift;
	};
};

/*
 * struct lp55xx_device_config
 * @reg_op_mode        : Chip specific OP MODE reg addr
 * @engine_busy        : Chip specific engine busy
 *			 (if not supported 153 us sleep)
 * @reset              : Chip specific reset command
 * @enable             : Chip specific enable command
 * @prog_mem_base      : Chip specific base reg address for chip SMEM programming
 * @reg_led_pwm_base   : Chip specific base reg address for LED PWM conf
 * @reg_led_current_base : Chip specific base reg address for LED current conf
 * @pages_per_engine   : Assigned pages for each engine
 *                       (if not set chip doesn't support pages)
 * @max_channel        : Maximum number of channels
 * @post_init_device   : Chip specific initialization code
 * @brightness_fn      : Brightness function
 * @multicolor_brightness_fn : Multicolor brightness function
 * @set_led_current    : LED current set function
 * @firmware_cb        : Call function when the firmware is loaded
 * @run_engine         : Run internal engine for pattern
 * @dev_attr_group     : Device specific attributes
 */
struct lp55xx_device_config {
	const struct lp55xx_reg reg_op_mode; /* addr, shift */
	const struct lp55xx_reg reg_exec; /* addr, shift */
	const struct lp55xx_reg engine_busy; /* addr, mask */
	const struct lp55xx_reg reset;
	const struct lp55xx_reg enable;
	const struct lp55xx_reg prog_mem_base;
	const struct lp55xx_reg reg_led_pwm_base;
	const struct lp55xx_reg reg_led_current_base;
	const int pages_per_engine;
	const int max_channel;

	/* define if the device has specific initialization process */
	int (*post_init_device) (struct lp55xx_chip *chip);

	/* set LED brightness */
	int (*brightness_fn)(struct lp55xx_led *led);

	/* set multicolor LED brightness */
	int (*multicolor_brightness_fn)(struct lp55xx_led *led);

	/* current setting function */
	void (*set_led_current) (struct lp55xx_led *led, u8 led_current);

	/* access program memory when the firmware is loaded */
	void (*firmware_cb)(struct lp55xx_chip *chip);

	/* used for running firmware LED patterns */
	void (*run_engine) (struct lp55xx_chip *chip, bool start);

	/* additional device specific attributes */
	const struct attribute_group *dev_attr_group;
};

/*
 * struct lp55xx_engine
 * @mode       : Engine mode
 * @led_mux    : Mux bits for LED selection. Only used in LP5523
 */
struct lp55xx_engine {
	enum lp55xx_engine_mode mode;
	u16 led_mux;
};

/*
 * struct lp55xx_chip
 * @cl         : I2C communication for access registers
 * @pdata      : Platform specific data
 * @lock       : Lock for user-space interface
 * @num_leds   : Number of registered LEDs
 * @cfg        : Device specific configuration data
 * @engine_idx : Selected engine number
 * @engines    : Engine structure for the device attribute R/W interface
 * @fw         : Firmware data for running a LED pattern
 */
struct lp55xx_chip {
	struct i2c_client *cl;
	struct clk *clk;
	struct lp55xx_platform_data *pdata;
	struct mutex lock;	/* lock for user-space interface */
	int num_leds;
	const struct lp55xx_device_config *cfg;
	enum lp55xx_engine_index engine_idx;
	struct lp55xx_engine engines[LP55XX_ENGINE_MAX];
	const struct firmware *fw;
};

/*
 * struct lp55xx_led
 * @chan_nr         : Channel number
 * @cdev            : LED class device
 * @mc_cdev         : Multi color class device
 * @color_components: Multi color LED map information
 * @led_current     : Current setting at each led channel
 * @max_current     : Maximun current at each led channel
 * @brightness      : Brightness value
 * @chip            : The lp55xx chip data
 */
struct lp55xx_led {
	int chan_nr;
	struct led_classdev cdev;
	struct led_classdev_mc mc_cdev;
	u8 led_current;
	u8 max_current;
	u8 brightness;
	struct lp55xx_chip *chip;
};

/* register access */
extern int lp55xx_write(struct lp55xx_chip *chip, u8 reg, u8 val);
extern int lp55xx_read(struct lp55xx_chip *chip, u8 reg, u8 *val);
extern int lp55xx_update_bits(struct lp55xx_chip *chip, u8 reg,
			u8 mask, u8 val);

/* external clock detection */
extern bool lp55xx_is_extclk_used(struct lp55xx_chip *chip);

/* common chip functions */
extern void lp55xx_stop_all_engine(struct lp55xx_chip *chip);
extern void lp55xx_load_engine(struct lp55xx_chip *chip);
extern int lp55xx_run_engine_common(struct lp55xx_chip *chip);
extern int lp55xx_update_program_memory(struct lp55xx_chip *chip,
					const u8 *data, size_t size);
extern void lp55xx_firmware_loaded_cb(struct lp55xx_chip *chip);
extern int lp55xx_led_brightness(struct lp55xx_led *led);
extern int lp55xx_multicolor_brightness(struct lp55xx_led *led);
extern void lp55xx_set_led_current(struct lp55xx_led *led, u8 led_current);

/* common probe/remove function */
extern int lp55xx_probe(struct i2c_client *client);
extern void lp55xx_remove(struct i2c_client *client);

#endif /* _LEDS_LP55XX_COMMON_H */