1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2020 Marek Vasut <marex@denx.de>
5 * Based on rpi_touchscreen.c by Eric Anholt <eric@anholt.net>
8 #include <linux/backlight.h>
10 #include <linux/gpio/driver.h>
11 #include <linux/i2c.h>
12 #include <linux/init.h>
13 #include <linux/interrupt.h>
14 #include <linux/module.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/driver.h>
17 #include <linux/regulator/machine.h>
18 #include <linux/regulator/of_regulator.h>
19 #include <linux/slab.h>
21 /* I2C registers of the Atmel microcontroller. */
23 #define REG_PORTA 0x81
24 #define REG_PORTB 0x82
25 #define REG_PORTC 0x83
26 #define REG_POWERON 0x85
28 #define REG_ADDR_L 0x8c
29 #define REG_ADDR_H 0x8d
30 #define REG_WRITE_DATA_H 0x90
31 #define REG_WRITE_DATA_L 0x91
33 #define PA_LCD_DITHB BIT(0)
34 #define PA_LCD_MODE BIT(1)
35 #define PA_LCD_LR BIT(2)
36 #define PA_LCD_UD BIT(3)
38 #define PB_BRIDGE_PWRDNX_N BIT(0)
39 #define PB_LCD_VCC_N BIT(1)
40 #define PB_LCD_MAIN BIT(7)
42 #define PC_LED_EN BIT(0)
43 #define PC_RST_TP_N BIT(1)
44 #define PC_RST_LCD_N BIT(2)
45 #define PC_RST_BRIDGE_N BIT(3)
48 RST_BRIDGE_N
, /* TC358762 bridge reset */
49 RST_TP_N
, /* Touch controller reset */
53 struct gpio_signal_mappings
{
58 static const struct gpio_signal_mappings mappings
[NUM_GPIO
] = {
59 [RST_BRIDGE_N
] = { REG_PORTC
, PC_RST_BRIDGE_N
| PC_RST_LCD_N
},
60 [RST_TP_N
] = { REG_PORTC
, PC_RST_TP_N
},
64 /* lock to serialise overall accesses to the Atmel */
66 struct regmap
*regmap
;
67 bool gpio_states
[NUM_GPIO
];
73 static const struct regmap_config attiny_regmap_config
= {
77 .max_register
= REG_WRITE_DATA_L
,
78 .cache_type
= REGCACHE_MAPLE
,
81 static int attiny_set_port_state(struct attiny_lcd
*state
, int reg
, u8 val
)
83 state
->port_states
[reg
- REG_PORTA
] = val
;
84 return regmap_write(state
->regmap
, reg
, val
);
87 static u8
attiny_get_port_state(struct attiny_lcd
*state
, int reg
)
89 return state
->port_states
[reg
- REG_PORTA
];
92 static int attiny_lcd_power_enable(struct regulator_dev
*rdev
)
94 struct attiny_lcd
*state
= rdev_get_drvdata(rdev
);
96 mutex_lock(&state
->lock
);
98 /* Ensure bridge, and tp stay in reset */
99 attiny_set_port_state(state
, REG_PORTC
, 0);
100 usleep_range(5000, 10000);
102 /* Default to the same orientation as the closed source
103 * firmware used for the panel. Runtime rotation
104 * configuration will be supported using VC4's plane
107 attiny_set_port_state(state
, REG_PORTA
, PA_LCD_LR
);
108 usleep_range(5000, 10000);
109 /* Main regulator on, and power to the panel (LCD_VCC_N) */
110 attiny_set_port_state(state
, REG_PORTB
, PB_LCD_MAIN
);
111 usleep_range(5000, 10000);
112 /* Bring controllers out of reset */
113 attiny_set_port_state(state
, REG_PORTC
, PC_LED_EN
);
117 mutex_unlock(&state
->lock
);
122 static int attiny_lcd_power_disable(struct regulator_dev
*rdev
)
124 struct attiny_lcd
*state
= rdev_get_drvdata(rdev
);
126 mutex_lock(&state
->lock
);
128 regmap_write(rdev
->regmap
, REG_PWM
, 0);
129 usleep_range(5000, 10000);
131 attiny_set_port_state(state
, REG_PORTA
, 0);
132 usleep_range(5000, 10000);
133 attiny_set_port_state(state
, REG_PORTB
, PB_LCD_VCC_N
);
134 usleep_range(5000, 10000);
135 attiny_set_port_state(state
, REG_PORTC
, 0);
138 mutex_unlock(&state
->lock
);
143 static int attiny_lcd_power_is_enabled(struct regulator_dev
*rdev
)
145 struct attiny_lcd
*state
= rdev_get_drvdata(rdev
);
149 mutex_lock(&state
->lock
);
151 for (i
= 0; i
< 10; i
++) {
152 ret
= regmap_read(rdev
->regmap
, REG_PORTC
, &data
);
155 usleep_range(10000, 12000);
158 mutex_unlock(&state
->lock
);
163 return data
& PC_RST_BRIDGE_N
;
166 static const struct regulator_init_data attiny_regulator_default
= {
168 .valid_ops_mask
= REGULATOR_CHANGE_STATUS
,
172 static const struct regulator_ops attiny_regulator_ops
= {
173 .enable
= attiny_lcd_power_enable
,
174 .disable
= attiny_lcd_power_disable
,
175 .is_enabled
= attiny_lcd_power_is_enabled
,
178 static const struct regulator_desc attiny_regulator
= {
179 .name
= "tc358762-power",
180 .ops
= &attiny_regulator_ops
,
181 .type
= REGULATOR_VOLTAGE
,
182 .owner
= THIS_MODULE
,
185 static int attiny_update_status(struct backlight_device
*bl
)
187 struct attiny_lcd
*state
= bl_get_data(bl
);
188 struct regmap
*regmap
= state
->regmap
;
189 int brightness
= backlight_get_brightness(bl
);
192 mutex_lock(&state
->lock
);
194 for (i
= 0; i
< 10; i
++) {
195 ret
= regmap_write(regmap
, REG_PWM
, brightness
);
200 mutex_unlock(&state
->lock
);
205 static const struct backlight_ops attiny_bl
= {
206 .update_status
= attiny_update_status
,
209 static int attiny_gpio_get_direction(struct gpio_chip
*gc
, unsigned int off
)
211 return GPIO_LINE_DIRECTION_OUT
;
214 static void attiny_gpio_set(struct gpio_chip
*gc
, unsigned int off
, int val
)
216 struct attiny_lcd
*state
= gpiochip_get_data(gc
);
222 mutex_lock(&state
->lock
);
224 last_val
= attiny_get_port_state(state
, mappings
[off
].reg
);
226 last_val
|= mappings
[off
].mask
;
228 last_val
&= ~mappings
[off
].mask
;
230 attiny_set_port_state(state
, mappings
[off
].reg
, last_val
);
232 if (off
== RST_BRIDGE_N
&& val
) {
233 usleep_range(5000, 8000);
234 regmap_write(state
->regmap
, REG_ADDR_H
, 0x04);
235 usleep_range(5000, 8000);
236 regmap_write(state
->regmap
, REG_ADDR_L
, 0x7c);
237 usleep_range(5000, 8000);
238 regmap_write(state
->regmap
, REG_WRITE_DATA_H
, 0x00);
239 usleep_range(5000, 8000);
240 regmap_write(state
->regmap
, REG_WRITE_DATA_L
, 0x00);
245 mutex_unlock(&state
->lock
);
248 static int attiny_i2c_read(struct i2c_client
*client
, u8 reg
, unsigned int *buf
)
250 struct i2c_msg msgs
[1];
251 u8 addr_buf
[1] = { reg
};
252 u8 data_buf
[1] = { 0, };
255 /* Write register address */
256 msgs
[0].addr
= client
->addr
;
258 msgs
[0].len
= ARRAY_SIZE(addr_buf
);
259 msgs
[0].buf
= addr_buf
;
261 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
262 if (ret
!= ARRAY_SIZE(msgs
))
265 usleep_range(5000, 10000);
267 /* Read data from register */
268 msgs
[0].addr
= client
->addr
;
269 msgs
[0].flags
= I2C_M_RD
;
271 msgs
[0].buf
= data_buf
;
273 ret
= i2c_transfer(client
->adapter
, msgs
, ARRAY_SIZE(msgs
));
274 if (ret
!= ARRAY_SIZE(msgs
))
282 * I2C driver interface functions
284 static int attiny_i2c_probe(struct i2c_client
*i2c
)
286 struct backlight_properties props
= { };
287 struct regulator_config config
= { };
288 struct backlight_device
*bl
;
289 struct regulator_dev
*rdev
;
290 struct attiny_lcd
*state
;
291 struct regmap
*regmap
;
295 state
= devm_kzalloc(&i2c
->dev
, sizeof(*state
), GFP_KERNEL
);
299 mutex_init(&state
->lock
);
300 i2c_set_clientdata(i2c
, state
);
302 regmap
= devm_regmap_init_i2c(i2c
, &attiny_regmap_config
);
303 if (IS_ERR(regmap
)) {
304 ret
= PTR_ERR(regmap
);
305 dev_err(&i2c
->dev
, "Failed to allocate register map: %d\n",
310 ret
= attiny_i2c_read(i2c
, REG_ID
, &data
);
312 dev_err(&i2c
->dev
, "Failed to read REG_ID reg: %d\n", ret
);
317 case 0xde: /* ver 1 */
318 case 0xc3: /* ver 2 */
321 dev_err(&i2c
->dev
, "Unknown Atmel firmware revision: 0x%02x\n", data
);
326 regmap_write(regmap
, REG_POWERON
, 0);
328 regmap_write(regmap
, REG_PWM
, 0);
330 config
.dev
= &i2c
->dev
;
331 config
.regmap
= regmap
;
332 config
.of_node
= i2c
->dev
.of_node
;
333 config
.init_data
= &attiny_regulator_default
;
334 config
.driver_data
= state
;
336 rdev
= devm_regulator_register(&i2c
->dev
, &attiny_regulator
, &config
);
338 dev_err(&i2c
->dev
, "Failed to register ATTINY regulator\n");
343 props
.type
= BACKLIGHT_RAW
;
344 props
.max_brightness
= 0xff;
346 state
->regmap
= regmap
;
348 bl
= devm_backlight_device_register(&i2c
->dev
, dev_name(&i2c
->dev
),
349 &i2c
->dev
, state
, &attiny_bl
,
356 bl
->props
.brightness
= 0xff;
358 state
->gc
.parent
= &i2c
->dev
;
359 state
->gc
.label
= i2c
->name
;
360 state
->gc
.owner
= THIS_MODULE
;
362 state
->gc
.ngpio
= NUM_GPIO
;
364 state
->gc
.set
= attiny_gpio_set
;
365 state
->gc
.get_direction
= attiny_gpio_get_direction
;
366 state
->gc
.can_sleep
= true;
368 ret
= devm_gpiochip_add_data(&i2c
->dev
, &state
->gc
, state
);
370 dev_err(&i2c
->dev
, "Failed to create gpiochip: %d\n", ret
);
377 mutex_destroy(&state
->lock
);
382 static void attiny_i2c_remove(struct i2c_client
*client
)
384 struct attiny_lcd
*state
= i2c_get_clientdata(client
);
386 mutex_destroy(&state
->lock
);
389 static const struct of_device_id attiny_dt_ids
[] = {
390 { .compatible
= "raspberrypi,7inch-touchscreen-panel-regulator" },
393 MODULE_DEVICE_TABLE(of
, attiny_dt_ids
);
395 static struct i2c_driver attiny_regulator_driver
= {
397 .name
= "rpi_touchscreen_attiny",
398 .probe_type
= PROBE_PREFER_ASYNCHRONOUS
,
399 .of_match_table
= attiny_dt_ids
,
401 .probe
= attiny_i2c_probe
,
402 .remove
= attiny_i2c_remove
,
405 module_i2c_driver(attiny_regulator_driver
);
407 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
408 MODULE_DESCRIPTION("Regulator device driver for Raspberry Pi 7-inch touchscreen");
409 MODULE_LICENSE("GPL v2");