88#include <linux/backlight.h>
99#include <linux/err.h>
1010#include <linux/gpio.h>
11+ #include <linux/gpio/driver.h>
1112#include <linux/i2c.h>
1213#include <linux/init.h>
1314#include <linux/interrupt.h>
4445#define PC_RST_LCD_N BIT(2)
4546#define PC_RST_BRIDGE_N BIT(3)
4647
48+ enum gpio_signals {
49+ RST_BRIDGE_N , /* TC358762 bridge reset */
50+ RST_TP_N , /* Touch controller reset */
51+ NUM_GPIO
52+ };
53+
54+ struct gpio_signal_mappings {
55+ unsigned int reg ;
56+ unsigned int mask ;
57+ };
58+
59+ static const struct gpio_signal_mappings mappings [NUM_GPIO ] = {
60+ [RST_BRIDGE_N ] = { REG_PORTC , PC_RST_BRIDGE_N | PC_RST_LCD_N },
61+ [RST_TP_N ] = { REG_PORTC , PC_RST_TP_N },
62+ };
63+
4764struct attiny_lcd {
4865 /* lock to serialise overall accesses to the Atmel */
4966 struct mutex lock ;
5067 struct regmap * regmap ;
68+ bool gpio_states [NUM_GPIO ];
69+ u8 port_states [3 ];
70+
71+ struct gpio_chip gc ;
5172};
5273
5374static const struct regmap_config attiny_regmap_config = {
@@ -58,41 +79,42 @@ static const struct regmap_config attiny_regmap_config = {
5879 .cache_type = REGCACHE_NONE ,
5980};
6081
82+ static int attiny_set_port_state (struct attiny_lcd * state , int reg , u8 val )
83+ {
84+ state -> port_states [reg - REG_PORTA ] = val ;
85+ return regmap_write (state -> regmap , reg , val );
86+ };
87+
88+ static u8 attiny_get_port_state (struct attiny_lcd * state , int reg )
89+ {
90+ return state -> port_states [reg - REG_PORTA ];
91+ };
92+
6193static int attiny_lcd_power_enable (struct regulator_dev * rdev )
6294{
6395 struct attiny_lcd * state = rdev_get_drvdata (rdev );
6496
6597 mutex_lock (& state -> lock );
6698
6799 /* Ensure bridge, and tp stay in reset */
68- regmap_write ( rdev -> regmap , REG_PORTC , 0 );
100+ attiny_set_port_state ( state , REG_PORTC , 0 );
69101 usleep_range (5000 , 10000 );
70102
71103 /* Default to the same orientation as the closed source
72104 * firmware used for the panel. Runtime rotation
73105 * configuration will be supported using VC4's plane
74106 * orientation bits.
75107 */
76- regmap_write ( rdev -> regmap , REG_PORTA , PA_LCD_LR );
108+ attiny_set_port_state ( state , REG_PORTA , PA_LCD_LR );
77109 usleep_range (5000 , 10000 );
78- regmap_write (rdev -> regmap , REG_PORTB , PB_LCD_MAIN );
110+ /* Main regulator on, and power to the panel (LCD_VCC_N) */
111+ attiny_set_port_state (state , REG_PORTB , PB_LCD_MAIN );
79112 usleep_range (5000 , 10000 );
80113 /* Bring controllers out of reset */
81- regmap_write (rdev -> regmap , REG_PORTC ,
82- PC_LED_EN | PC_RST_BRIDGE_N | PC_RST_LCD_N | PC_RST_TP_N );
114+ attiny_set_port_state (state , REG_PORTC , PC_LED_EN );
83115
84116 msleep (80 );
85117
86- regmap_write (rdev -> regmap , REG_ADDR_H , 0x04 );
87- usleep_range (5000 , 8000 );
88- regmap_write (rdev -> regmap , REG_ADDR_L , 0x7c );
89- usleep_range (5000 , 8000 );
90- regmap_write (rdev -> regmap , REG_WRITE_DATA_H , 0x00 );
91- usleep_range (5000 , 8000 );
92- regmap_write (rdev -> regmap , REG_WRITE_DATA_L , 0x00 );
93-
94- msleep (100 );
95-
96118 mutex_unlock (& state -> lock );
97119
98120 return 0 ;
@@ -106,11 +128,12 @@ static int attiny_lcd_power_disable(struct regulator_dev *rdev)
106128
107129 regmap_write (rdev -> regmap , REG_PWM , 0 );
108130 usleep_range (5000 , 10000 );
109- regmap_write (rdev -> regmap , REG_PORTA , 0 );
131+
132+ attiny_set_port_state (state , REG_PORTA , 0 );
110133 usleep_range (5000 , 10000 );
111- regmap_write ( rdev -> regmap , REG_PORTB , PB_LCD_VCC_N );
134+ attiny_set_port_state ( state , REG_PORTB , PB_LCD_VCC_N );
112135 usleep_range (5000 , 10000 );
113- regmap_write ( rdev -> regmap , REG_PORTC , 0 );
136+ attiny_set_port_state ( state , REG_PORTC , 0 );
114137 msleep (30 );
115138
116139 mutex_unlock (& state -> lock );
@@ -211,6 +234,45 @@ static const struct backlight_ops attiny_bl = {
211234 .get_brightness = attiny_get_brightness ,
212235};
213236
237+ static int attiny_gpio_get_direction (struct gpio_chip * gc , unsigned int off )
238+ {
239+ return GPIO_LINE_DIRECTION_OUT ;
240+ }
241+
242+ static void attiny_gpio_set (struct gpio_chip * gc , unsigned int off , int val )
243+ {
244+ struct attiny_lcd * state = gpiochip_get_data (gc );
245+ u8 last_val ;
246+
247+ if (off >= NUM_GPIO )
248+ return ;
249+
250+ mutex_lock (& state -> lock );
251+
252+ last_val = attiny_get_port_state (state , mappings [off ].reg );
253+ if (val )
254+ last_val |= mappings [off ].mask ;
255+ else
256+ last_val &= ~mappings [off ].mask ;
257+
258+ attiny_set_port_state (state , mappings [off ].reg , last_val );
259+
260+ if (off == RST_BRIDGE_N && val ) {
261+ usleep_range (5000 , 8000 );
262+ regmap_write (state -> regmap , REG_ADDR_H , 0x04 );
263+ usleep_range (5000 , 8000 );
264+ regmap_write (state -> regmap , REG_ADDR_L , 0x7c );
265+ usleep_range (5000 , 8000 );
266+ regmap_write (state -> regmap , REG_WRITE_DATA_H , 0x00 );
267+ usleep_range (5000 , 8000 );
268+ regmap_write (state -> regmap , REG_WRITE_DATA_L , 0x00 );
269+
270+ msleep (100 );
271+ }
272+
273+ mutex_unlock (& state -> lock );
274+ }
275+
214276/*
215277 * I2C driver interface functions
216278 */
@@ -289,6 +351,23 @@ static int attiny_i2c_probe(struct i2c_client *i2c,
289351
290352 bl -> props .brightness = 0xff ;
291353
354+ state -> gc .parent = & i2c -> dev ;
355+ state -> gc .label = i2c -> name ;
356+ state -> gc .owner = THIS_MODULE ;
357+ state -> gc .of_node = i2c -> dev .of_node ;
358+ state -> gc .base = -1 ;
359+ state -> gc .ngpio = NUM_GPIO ;
360+
361+ state -> gc .set = attiny_gpio_set ;
362+ state -> gc .get_direction = attiny_gpio_get_direction ;
363+ state -> gc .can_sleep = true;
364+
365+ ret = devm_gpiochip_add_data (& i2c -> dev , & state -> gc , state );
366+ if (ret ) {
367+ dev_err (& i2c -> dev , "Failed to create gpiochip: %d\n" , ret );
368+ goto error ;
369+ }
370+
292371 return 0 ;
293372
294373error :
0 commit comments