1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020 Marek Vasut <marex@denx.de> 4 * 5 * Based on rpi_touchscreen.c by Eric Anholt <eric@anholt.net> 6 */ 7 8 #include <linux/backlight.h> 9 #include <linux/err.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> 20 21 /* I2C registers of the Atmel microcontroller. */ 22 #define REG_ID 0x80 23 #define REG_PORTA 0x81 24 #define REG_PORTB 0x82 25 #define REG_PORTC 0x83 26 #define REG_POWERON 0x85 27 #define REG_PWM 0x86 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 32 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) 37 38 #define PB_BRIDGE_PWRDNX_N BIT(0) 39 #define PB_LCD_VCC_N BIT(1) 40 #define PB_LCD_MAIN BIT(7) 41 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) 46 47 enum gpio_signals { 48 RST_BRIDGE_N, /* TC358762 bridge reset */ 49 RST_TP_N, /* Touch controller reset */ 50 NUM_GPIO 51 }; 52 53 struct gpio_signal_mappings { 54 unsigned int reg; 55 unsigned int mask; 56 }; 57 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 }, 61 }; 62 63 struct attiny_lcd { 64 /* lock to serialise overall accesses to the Atmel */ 65 struct mutex lock; 66 struct regmap *regmap; 67 bool gpio_states[NUM_GPIO]; 68 u8 port_states[3]; 69 70 struct gpio_chip gc; 71 }; 72 73 static const struct regmap_config attiny_regmap_config = { 74 .reg_bits = 8, 75 .val_bits = 8, 76 .disable_locking = 1, 77 .max_register = REG_WRITE_DATA_L, 78 .cache_type = REGCACHE_MAPLE, 79 }; 80 81 static int attiny_set_port_state(struct attiny_lcd *state, int reg, u8 val) 82 { 83 state->port_states[reg - REG_PORTA] = val; 84 return regmap_write(state->regmap, reg, val); 85 }; 86 87 static u8 attiny_get_port_state(struct attiny_lcd *state, int reg) 88 { 89 return state->port_states[reg - REG_PORTA]; 90 }; 91 92 static int attiny_lcd_power_enable(struct regulator_dev *rdev) 93 { 94 struct attiny_lcd *state = rdev_get_drvdata(rdev); 95 96 mutex_lock(&state->lock); 97 98 /* Ensure bridge, and tp stay in reset */ 99 attiny_set_port_state(state, REG_PORTC, 0); 100 usleep_range(5000, 10000); 101 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 105 * orientation bits. 106 */ 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); 114 115 msleep(80); 116 117 mutex_unlock(&state->lock); 118 119 return 0; 120 } 121 122 static int attiny_lcd_power_disable(struct regulator_dev *rdev) 123 { 124 struct attiny_lcd *state = rdev_get_drvdata(rdev); 125 126 mutex_lock(&state->lock); 127 128 regmap_write(rdev->regmap, REG_PWM, 0); 129 usleep_range(5000, 10000); 130 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); 136 msleep(30); 137 138 mutex_unlock(&state->lock); 139 140 return 0; 141 } 142 143 static int attiny_lcd_power_is_enabled(struct regulator_dev *rdev) 144 { 145 struct attiny_lcd *state = rdev_get_drvdata(rdev); 146 unsigned int data; 147 int ret, i; 148 149 mutex_lock(&state->lock); 150 151 for (i = 0; i < 10; i++) { 152 ret = regmap_read(rdev->regmap, REG_PORTC, &data); 153 if (!ret) 154 break; 155 usleep_range(10000, 12000); 156 } 157 158 mutex_unlock(&state->lock); 159 160 if (ret < 0) 161 return ret; 162 163 return data & PC_RST_BRIDGE_N; 164 } 165 166 static const struct regulator_init_data attiny_regulator_default = { 167 .constraints = { 168 .valid_ops_mask = REGULATOR_CHANGE_STATUS, 169 }, 170 }; 171 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, 176 }; 177 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, 183 }; 184 185 static int attiny_update_status(struct backlight_device *bl) 186 { 187 struct attiny_lcd *state = bl_get_data(bl); 188 struct regmap *regmap = state->regmap; 189 int brightness = backlight_get_brightness(bl); 190 int ret, i; 191 192 mutex_lock(&state->lock); 193 194 for (i = 0; i < 10; i++) { 195 ret = regmap_write(regmap, REG_PWM, brightness); 196 if (!ret) 197 break; 198 } 199 200 mutex_unlock(&state->lock); 201 202 return ret; 203 } 204 205 static const struct backlight_ops attiny_bl = { 206 .update_status = attiny_update_status, 207 }; 208 209 static int attiny_gpio_get_direction(struct gpio_chip *gc, unsigned int off) 210 { 211 return GPIO_LINE_DIRECTION_OUT; 212 } 213 214 static void attiny_gpio_set(struct gpio_chip *gc, unsigned int off, int val) 215 { 216 struct attiny_lcd *state = gpiochip_get_data(gc); 217 u8 last_val; 218 219 if (off >= NUM_GPIO) 220 return; 221 222 mutex_lock(&state->lock); 223 224 last_val = attiny_get_port_state(state, mappings[off].reg); 225 if (val) 226 last_val |= mappings[off].mask; 227 else 228 last_val &= ~mappings[off].mask; 229 230 attiny_set_port_state(state, mappings[off].reg, last_val); 231 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); 241 242 msleep(100); 243 } 244 245 mutex_unlock(&state->lock); 246 } 247 248 static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf) 249 { 250 struct i2c_msg msgs[1]; 251 u8 addr_buf[1] = { reg }; 252 u8 data_buf[1] = { 0, }; 253 int ret; 254 255 /* Write register address */ 256 msgs[0].addr = client->addr; 257 msgs[0].flags = 0; 258 msgs[0].len = ARRAY_SIZE(addr_buf); 259 msgs[0].buf = addr_buf; 260 261 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 262 if (ret != ARRAY_SIZE(msgs)) 263 return -EIO; 264 265 usleep_range(5000, 10000); 266 267 /* Read data from register */ 268 msgs[0].addr = client->addr; 269 msgs[0].flags = I2C_M_RD; 270 msgs[0].len = 1; 271 msgs[0].buf = data_buf; 272 273 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 274 if (ret != ARRAY_SIZE(msgs)) 275 return -EIO; 276 277 *buf = data_buf[0]; 278 return 0; 279 } 280 281 /* 282 * I2C driver interface functions 283 */ 284 static int attiny_i2c_probe(struct i2c_client *i2c) 285 { 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; 292 unsigned int data; 293 int ret; 294 295 state = devm_kzalloc(&i2c->dev, sizeof(*state), GFP_KERNEL); 296 if (!state) 297 return -ENOMEM; 298 299 mutex_init(&state->lock); 300 i2c_set_clientdata(i2c, state); 301 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", 306 ret); 307 goto error; 308 } 309 310 ret = attiny_i2c_read(i2c, REG_ID, &data); 311 if (ret < 0) { 312 dev_err(&i2c->dev, "Failed to read REG_ID reg: %d\n", ret); 313 goto error; 314 } 315 316 switch (data) { 317 case 0xde: /* ver 1 */ 318 case 0xc3: /* ver 2 */ 319 break; 320 default: 321 dev_err(&i2c->dev, "Unknown Atmel firmware revision: 0x%02x\n", data); 322 ret = -ENODEV; 323 goto error; 324 } 325 326 regmap_write(regmap, REG_POWERON, 0); 327 msleep(30); 328 regmap_write(regmap, REG_PWM, 0); 329 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; 335 336 rdev = devm_regulator_register(&i2c->dev, &attiny_regulator, &config); 337 if (IS_ERR(rdev)) { 338 dev_err(&i2c->dev, "Failed to register ATTINY regulator\n"); 339 ret = PTR_ERR(rdev); 340 goto error; 341 } 342 343 props.type = BACKLIGHT_RAW; 344 props.max_brightness = 0xff; 345 346 state->regmap = regmap; 347 348 bl = devm_backlight_device_register(&i2c->dev, dev_name(&i2c->dev), 349 &i2c->dev, state, &attiny_bl, 350 &props); 351 if (IS_ERR(bl)) { 352 ret = PTR_ERR(bl); 353 goto error; 354 } 355 356 bl->props.brightness = 0xff; 357 358 state->gc.parent = &i2c->dev; 359 state->gc.label = i2c->name; 360 state->gc.owner = THIS_MODULE; 361 state->gc.base = -1; 362 state->gc.ngpio = NUM_GPIO; 363 364 state->gc.set = attiny_gpio_set; 365 state->gc.get_direction = attiny_gpio_get_direction; 366 state->gc.can_sleep = true; 367 368 ret = devm_gpiochip_add_data(&i2c->dev, &state->gc, state); 369 if (ret) { 370 dev_err(&i2c->dev, "Failed to create gpiochip: %d\n", ret); 371 goto error; 372 } 373 374 return 0; 375 376 error: 377 mutex_destroy(&state->lock); 378 379 return ret; 380 } 381 382 static void attiny_i2c_remove(struct i2c_client *client) 383 { 384 struct attiny_lcd *state = i2c_get_clientdata(client); 385 386 mutex_destroy(&state->lock); 387 } 388 389 static const struct of_device_id attiny_dt_ids[] = { 390 { .compatible = "raspberrypi,7inch-touchscreen-panel-regulator" }, 391 {}, 392 }; 393 MODULE_DEVICE_TABLE(of, attiny_dt_ids); 394 395 static struct i2c_driver attiny_regulator_driver = { 396 .driver = { 397 .name = "rpi_touchscreen_attiny", 398 .probe_type = PROBE_PREFER_ASYNCHRONOUS, 399 .of_match_table = attiny_dt_ids, 400 }, 401 .probe = attiny_i2c_probe, 402 .remove = attiny_i2c_remove, 403 }; 404 405 module_i2c_driver(attiny_regulator_driver); 406 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"); 410