1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2023 Loongson Technology Corporation Limited 4 */ 5 6 #include <drm/drm_managed.h> 7 #include <drm/drm_print.h> 8 9 #include "lsdc_drv.h" 10 #include "lsdc_output.h" 11 12 /* 13 * __lsdc_gpio_i2c_set - set the state of a gpio pin indicated by mask 14 * @mask: gpio pin mask 15 * @state: "0" for low, "1" for high 16 */ 17 static void __lsdc_gpio_i2c_set(struct lsdc_i2c * const li2c, int mask, int state) 18 { 19 struct lsdc_device *ldev = to_lsdc(li2c->ddev); 20 unsigned long flags; 21 u8 val; 22 23 spin_lock_irqsave(&ldev->reglock, flags); 24 25 if (state) { 26 /* 27 * Setting this pin as input directly, write 1 for input. 28 * The external pull-up resistor will pull the level up 29 */ 30 val = readb(li2c->dir_reg); 31 val |= mask; 32 writeb(val, li2c->dir_reg); 33 } else { 34 /* First set this pin as output, write 0 for output */ 35 val = readb(li2c->dir_reg); 36 val &= ~mask; 37 writeb(val, li2c->dir_reg); 38 39 /* Then, make this pin output 0 */ 40 val = readb(li2c->dat_reg); 41 val &= ~mask; 42 writeb(val, li2c->dat_reg); 43 } 44 45 spin_unlock_irqrestore(&ldev->reglock, flags); 46 } 47 48 /* 49 * __lsdc_gpio_i2c_get - read value back from the gpio pin indicated by mask 50 * @mask: gpio pin mask 51 * return "0" for low, "1" for high 52 */ 53 static int __lsdc_gpio_i2c_get(struct lsdc_i2c * const li2c, int mask) 54 { 55 struct lsdc_device *ldev = to_lsdc(li2c->ddev); 56 unsigned long flags; 57 u8 val; 58 59 spin_lock_irqsave(&ldev->reglock, flags); 60 61 /* First set this pin as input */ 62 val = readb(li2c->dir_reg); 63 val |= mask; 64 writeb(val, li2c->dir_reg); 65 66 /* Then get level state from this pin */ 67 val = readb(li2c->dat_reg); 68 69 spin_unlock_irqrestore(&ldev->reglock, flags); 70 71 return (val & mask) ? 1 : 0; 72 } 73 74 static void lsdc_gpio_i2c_set_sda(void *i2c, int state) 75 { 76 struct lsdc_i2c * const li2c = (struct lsdc_i2c *)i2c; 77 /* set state on the li2c->sda pin */ 78 return __lsdc_gpio_i2c_set(li2c, li2c->sda, state); 79 } 80 81 static void lsdc_gpio_i2c_set_scl(void *i2c, int state) 82 { 83 struct lsdc_i2c * const li2c = (struct lsdc_i2c *)i2c; 84 /* set state on the li2c->scl pin */ 85 return __lsdc_gpio_i2c_set(li2c, li2c->scl, state); 86 } 87 88 static int lsdc_gpio_i2c_get_sda(void *i2c) 89 { 90 struct lsdc_i2c * const li2c = (struct lsdc_i2c *)i2c; 91 /* read value from the li2c->sda pin */ 92 return __lsdc_gpio_i2c_get(li2c, li2c->sda); 93 } 94 95 static int lsdc_gpio_i2c_get_scl(void *i2c) 96 { 97 struct lsdc_i2c * const li2c = (struct lsdc_i2c *)i2c; 98 /* read the value from the li2c->scl pin */ 99 return __lsdc_gpio_i2c_get(li2c, li2c->scl); 100 } 101 102 static void lsdc_destroy_i2c(struct drm_device *ddev, void *data) 103 { 104 struct lsdc_i2c *li2c = (struct lsdc_i2c *)data; 105 106 if (li2c) { 107 i2c_del_adapter(&li2c->adapter); 108 kfree(li2c); 109 } 110 } 111 112 /* 113 * The DC in ls7a1000/ls7a2000/ls2k2000 has builtin gpio hardware 114 * 115 * @reg_base: gpio reg base 116 * @index: output channel index, 0 for PIPE0, 1 for PIPE1 117 */ 118 int lsdc_create_i2c_chan(struct drm_device *ddev, 119 struct lsdc_display_pipe *dispipe, 120 unsigned int index) 121 { 122 struct lsdc_device *ldev = to_lsdc(ddev); 123 struct i2c_adapter *adapter; 124 struct lsdc_i2c *li2c; 125 int ret; 126 127 li2c = kzalloc(sizeof(*li2c), GFP_KERNEL); 128 if (!li2c) 129 return -ENOMEM; 130 131 dispipe->li2c = li2c; 132 133 if (index == 0) { 134 li2c->sda = 0x01; /* pin 0 */ 135 li2c->scl = 0x02; /* pin 1 */ 136 } else if (index == 1) { 137 li2c->sda = 0x04; /* pin 2 */ 138 li2c->scl = 0x08; /* pin 3 */ 139 } else { 140 return -ENOENT; 141 } 142 143 li2c->ddev = ddev; 144 li2c->dir_reg = ldev->reg_base + LS7A_DC_GPIO_DIR_REG; 145 li2c->dat_reg = ldev->reg_base + LS7A_DC_GPIO_DAT_REG; 146 147 li2c->bit.setsda = lsdc_gpio_i2c_set_sda; 148 li2c->bit.setscl = lsdc_gpio_i2c_set_scl; 149 li2c->bit.getsda = lsdc_gpio_i2c_get_sda; 150 li2c->bit.getscl = lsdc_gpio_i2c_get_scl; 151 li2c->bit.udelay = 5; 152 li2c->bit.timeout = usecs_to_jiffies(2200); 153 li2c->bit.data = li2c; 154 155 adapter = &li2c->adapter; 156 adapter->algo_data = &li2c->bit; 157 adapter->owner = THIS_MODULE; 158 adapter->dev.parent = ddev->dev; 159 adapter->nr = -1; 160 161 snprintf(adapter->name, sizeof(adapter->name), "lsdc-i2c%u", index); 162 163 i2c_set_adapdata(adapter, li2c); 164 165 ret = i2c_bit_add_bus(adapter); 166 if (ret) { 167 kfree(li2c); 168 return ret; 169 } 170 171 ret = drmm_add_action_or_reset(ddev, lsdc_destroy_i2c, li2c); 172 if (ret) 173 return ret; 174 175 drm_info(ddev, "%s(sda pin mask=%u, scl pin mask=%u) created\n", 176 adapter->name, li2c->sda, li2c->scl); 177 178 return 0; 179 } 180