1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2024 Waveshare International Limited 4 * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. 5 */ 6 7 #include <linux/backlight.h> 8 #include <linux/err.h> 9 #include <linux/fb.h> 10 #include <linux/gpio/driver.h> 11 #include <linux/module.h> 12 #include <linux/of.h> 13 #include <linux/regmap.h> 14 15 /* I2C registers of the microcontroller. */ 16 #define REG_TP 0x94 17 #define REG_LCD 0x95 18 #define REG_PWM 0x96 19 #define REG_SIZE 0x97 20 #define REG_ID 0x98 21 #define REG_VERSION 0x99 22 23 enum { 24 GPIO_AVDD = 0, 25 GPIO_PANEL_RESET = 1, 26 GPIO_BL_ENABLE = 2, 27 GPIO_IOVCC = 4, 28 GPIO_VCC = 8, 29 GPIO_TS_RESET = 9, 30 }; 31 32 #define NUM_GPIO 16 33 34 struct waveshare_gpio { 35 struct mutex dir_lock; 36 struct mutex pwr_lock; 37 struct regmap *regmap; 38 u16 poweron_state; 39 40 struct gpio_chip gc; 41 }; 42 43 static const struct regmap_config waveshare_gpio_regmap_config = { 44 .reg_bits = 8, 45 .val_bits = 8, 46 .max_register = REG_VERSION, 47 }; 48 49 static int waveshare_gpio_get(struct waveshare_gpio *state, unsigned int offset) 50 { 51 u16 pwr_state; 52 53 guard(mutex)(&state->pwr_lock); 54 pwr_state = state->poweron_state & BIT(offset); 55 56 return !!pwr_state; 57 } 58 59 static int waveshare_gpio_set(struct waveshare_gpio *state, unsigned int offset, int value) 60 { 61 u16 last_val; 62 int err; 63 64 guard(mutex)(&state->pwr_lock); 65 66 last_val = state->poweron_state; 67 if (value) 68 last_val |= BIT(offset); 69 else 70 last_val &= ~BIT(offset); 71 72 state->poweron_state = last_val; 73 74 err = regmap_write(state->regmap, REG_TP, last_val >> 8); 75 if (!err) 76 err = regmap_write(state->regmap, REG_LCD, last_val & 0xff); 77 78 return err; 79 } 80 81 static int waveshare_gpio_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) 82 { 83 return GPIO_LINE_DIRECTION_OUT; 84 } 85 86 static int waveshare_gpio_gpio_get(struct gpio_chip *gc, unsigned int offset) 87 { 88 struct waveshare_gpio *state = gpiochip_get_data(gc); 89 90 return waveshare_gpio_get(state, offset); 91 } 92 93 static int waveshare_gpio_gpio_set(struct gpio_chip *gc, unsigned int offset, int value) 94 { 95 struct waveshare_gpio *state = gpiochip_get_data(gc); 96 97 return waveshare_gpio_set(state, offset, value); 98 } 99 100 static int waveshare_gpio_update_status(struct backlight_device *bl) 101 { 102 struct waveshare_gpio *state = bl_get_data(bl); 103 int brightness = backlight_get_brightness(bl); 104 105 waveshare_gpio_set(state, GPIO_BL_ENABLE, brightness); 106 107 return regmap_write(state->regmap, REG_PWM, brightness); 108 } 109 110 static const struct backlight_ops waveshare_gpio_bl = { 111 .update_status = waveshare_gpio_update_status, 112 }; 113 114 static int waveshare_gpio_probe(struct i2c_client *i2c) 115 { 116 struct backlight_properties props = {}; 117 struct waveshare_gpio *state; 118 struct device *dev = &i2c->dev; 119 struct backlight_device *bl; 120 struct regmap *regmap; 121 unsigned int data; 122 int ret; 123 124 state = devm_kzalloc(dev, sizeof(*state), GFP_KERNEL); 125 if (!state) 126 return -ENOMEM; 127 128 ret = devm_mutex_init(dev, &state->dir_lock); 129 if (ret) 130 return ret; 131 132 ret = devm_mutex_init(dev, &state->pwr_lock); 133 if (ret) 134 return ret; 135 136 regmap = devm_regmap_init_i2c(i2c, &waveshare_gpio_regmap_config); 137 if (IS_ERR(regmap)) 138 return dev_err_probe(dev, PTR_ERR(regmap), "Failed to allocate register map\n"); 139 140 state->regmap = regmap; 141 i2c_set_clientdata(i2c, state); 142 143 ret = regmap_read(regmap, REG_ID, &data); 144 if (ret < 0) 145 return dev_err_probe(dev, ret, "Failed to read register\n"); 146 147 dev_dbg(dev, "waveshare panel hw id = 0x%x\n", data); 148 149 ret = regmap_read(regmap, REG_SIZE, &data); 150 if (ret < 0) 151 return dev_err_probe(dev, ret, "Failed to read register\n"); 152 153 dev_dbg(dev, "waveshare panel size = %d\n", data); 154 155 ret = regmap_read(regmap, REG_VERSION, &data); 156 if (ret < 0) 157 return dev_err_probe(dev, ret, "Failed to read register\n"); 158 159 dev_dbg(dev, "waveshare panel mcu version = 0x%x\n", data); 160 161 ret = waveshare_gpio_set(state, GPIO_TS_RESET, 1); 162 if (ret) 163 return dev_err_probe(dev, ret, "Failed to program GPIOs\n"); 164 165 msleep(20); 166 167 state->gc.parent = dev; 168 state->gc.label = i2c->name; 169 state->gc.owner = THIS_MODULE; 170 state->gc.base = -1; 171 state->gc.ngpio = NUM_GPIO; 172 173 /* it is output only */ 174 state->gc.get = waveshare_gpio_gpio_get; 175 state->gc.set = waveshare_gpio_gpio_set; 176 state->gc.get_direction = waveshare_gpio_gpio_get_direction; 177 state->gc.can_sleep = true; 178 179 ret = devm_gpiochip_add_data(dev, &state->gc, state); 180 if (ret) 181 return dev_err_probe(dev, ret, "Failed to create gpiochip\n"); 182 183 props.type = BACKLIGHT_RAW; 184 props.max_brightness = 255; 185 props.brightness = 255; 186 bl = devm_backlight_device_register(dev, dev_name(dev), dev, state, 187 &waveshare_gpio_bl, &props); 188 return PTR_ERR_OR_ZERO(bl); 189 } 190 191 static const struct of_device_id waveshare_gpio_dt_ids[] = { 192 { .compatible = "waveshare,dsi-touch-gpio" }, 193 {}, 194 }; 195 MODULE_DEVICE_TABLE(of, waveshare_gpio_dt_ids); 196 197 static struct i2c_driver waveshare_gpio_regulator_driver = { 198 .driver = { 199 .name = "waveshare-regulator", 200 .of_match_table = of_match_ptr(waveshare_gpio_dt_ids), 201 }, 202 .probe = waveshare_gpio_probe, 203 }; 204 205 module_i2c_driver(waveshare_gpio_regulator_driver); 206 207 MODULE_DESCRIPTION("GPIO controller driver for Waveshare DSI touch panels"); 208 MODULE_LICENSE("GPL"); 209