diff options
Diffstat (limited to 'drivers/gpio/gpio-crystalcove.c')
-rw-r--r-- | drivers/gpio/gpio-crystalcove.c | 54 |
1 files changed, 36 insertions, 18 deletions
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 2197368cc899..e60156ec0c18 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c | |||
@@ -90,8 +90,18 @@ static inline int to_reg(int gpio, enum ctrl_register reg_type) | |||
90 | { | 90 | { |
91 | int reg; | 91 | int reg; |
92 | 92 | ||
93 | if (gpio == 94) | 93 | if (gpio >= CRYSTALCOVE_GPIO_NUM) { |
94 | return GPIOPANELCTL; | 94 | /* |
95 | * Virtual GPIO called from ACPI, for now we only support | ||
96 | * the panel ctl. | ||
97 | */ | ||
98 | switch (gpio) { | ||
99 | case 0x5e: | ||
100 | return GPIOPANELCTL; | ||
101 | default: | ||
102 | return -EOPNOTSUPP; | ||
103 | } | ||
104 | } | ||
95 | 105 | ||
96 | if (reg_type == CTRL_IN) { | 106 | if (reg_type == CTRL_IN) { |
97 | if (gpio < 8) | 107 | if (gpio < 8) |
@@ -130,36 +140,36 @@ static void crystalcove_update_irq_ctrl(struct crystalcove_gpio *cg, int gpio) | |||
130 | static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio) | 140 | static int crystalcove_gpio_dir_in(struct gpio_chip *chip, unsigned gpio) |
131 | { | 141 | { |
132 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); | 142 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); |
143 | int reg = to_reg(gpio, CTRL_OUT); | ||
133 | 144 | ||
134 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | 145 | if (reg < 0) |
135 | return 0; | 146 | return 0; |
136 | 147 | ||
137 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), | 148 | return regmap_write(cg->regmap, reg, CTLO_INPUT_SET); |
138 | CTLO_INPUT_SET); | ||
139 | } | 149 | } |
140 | 150 | ||
141 | static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, | 151 | static int crystalcove_gpio_dir_out(struct gpio_chip *chip, unsigned gpio, |
142 | int value) | 152 | int value) |
143 | { | 153 | { |
144 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); | 154 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); |
155 | int reg = to_reg(gpio, CTRL_OUT); | ||
145 | 156 | ||
146 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | 157 | if (reg < 0) |
147 | return 0; | 158 | return 0; |
148 | 159 | ||
149 | return regmap_write(cg->regmap, to_reg(gpio, CTRL_OUT), | 160 | return regmap_write(cg->regmap, reg, CTLO_OUTPUT_SET | value); |
150 | CTLO_OUTPUT_SET | value); | ||
151 | } | 161 | } |
152 | 162 | ||
153 | static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio) | 163 | static int crystalcove_gpio_get(struct gpio_chip *chip, unsigned gpio) |
154 | { | 164 | { |
155 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); | 165 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); |
156 | int ret; | ||
157 | unsigned int val; | 166 | unsigned int val; |
167 | int ret, reg = to_reg(gpio, CTRL_IN); | ||
158 | 168 | ||
159 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | 169 | if (reg < 0) |
160 | return 0; | 170 | return 0; |
161 | 171 | ||
162 | ret = regmap_read(cg->regmap, to_reg(gpio, CTRL_IN), &val); | 172 | ret = regmap_read(cg->regmap, reg, &val); |
163 | if (ret) | 173 | if (ret) |
164 | return ret; | 174 | return ret; |
165 | 175 | ||
@@ -170,14 +180,15 @@ static void crystalcove_gpio_set(struct gpio_chip *chip, | |||
170 | unsigned gpio, int value) | 180 | unsigned gpio, int value) |
171 | { | 181 | { |
172 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); | 182 | struct crystalcove_gpio *cg = gpiochip_get_data(chip); |
183 | int reg = to_reg(gpio, CTRL_OUT); | ||
173 | 184 | ||
174 | if (gpio > CRYSTALCOVE_VGPIO_NUM) | 185 | if (reg < 0) |
175 | return; | 186 | return; |
176 | 187 | ||
177 | if (value) | 188 | if (value) |
178 | regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 1); | 189 | regmap_update_bits(cg->regmap, reg, 1, 1); |
179 | else | 190 | else |
180 | regmap_update_bits(cg->regmap, to_reg(gpio, CTRL_OUT), 1, 0); | 191 | regmap_update_bits(cg->regmap, reg, 1, 0); |
181 | } | 192 | } |
182 | 193 | ||
183 | static int crystalcove_irq_type(struct irq_data *data, unsigned type) | 194 | static int crystalcove_irq_type(struct irq_data *data, unsigned type) |
@@ -185,6 +196,9 @@ static int crystalcove_irq_type(struct irq_data *data, unsigned type) | |||
185 | struct crystalcove_gpio *cg = | 196 | struct crystalcove_gpio *cg = |
186 | gpiochip_get_data(irq_data_get_irq_chip_data(data)); | 197 | gpiochip_get_data(irq_data_get_irq_chip_data(data)); |
187 | 198 | ||
199 | if (data->hwirq >= CRYSTALCOVE_GPIO_NUM) | ||
200 | return 0; | ||
201 | |||
188 | switch (type) { | 202 | switch (type) { |
189 | case IRQ_TYPE_NONE: | 203 | case IRQ_TYPE_NONE: |
190 | cg->intcnt_value = CTLI_INTCNT_DIS; | 204 | cg->intcnt_value = CTLI_INTCNT_DIS; |
@@ -235,8 +249,10 @@ static void crystalcove_irq_unmask(struct irq_data *data) | |||
235 | struct crystalcove_gpio *cg = | 249 | struct crystalcove_gpio *cg = |
236 | gpiochip_get_data(irq_data_get_irq_chip_data(data)); | 250 | gpiochip_get_data(irq_data_get_irq_chip_data(data)); |
237 | 251 | ||
238 | cg->set_irq_mask = false; | 252 | if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { |
239 | cg->update |= UPDATE_IRQ_MASK; | 253 | cg->set_irq_mask = false; |
254 | cg->update |= UPDATE_IRQ_MASK; | ||
255 | } | ||
240 | } | 256 | } |
241 | 257 | ||
242 | static void crystalcove_irq_mask(struct irq_data *data) | 258 | static void crystalcove_irq_mask(struct irq_data *data) |
@@ -244,8 +260,10 @@ static void crystalcove_irq_mask(struct irq_data *data) | |||
244 | struct crystalcove_gpio *cg = | 260 | struct crystalcove_gpio *cg = |
245 | gpiochip_get_data(irq_data_get_irq_chip_data(data)); | 261 | gpiochip_get_data(irq_data_get_irq_chip_data(data)); |
246 | 262 | ||
247 | cg->set_irq_mask = true; | 263 | if (data->hwirq < CRYSTALCOVE_GPIO_NUM) { |
248 | cg->update |= UPDATE_IRQ_MASK; | 264 | cg->set_irq_mask = true; |
265 | cg->update |= UPDATE_IRQ_MASK; | ||
266 | } | ||
249 | } | 267 | } |
250 | 268 | ||
251 | static struct irq_chip crystalcove_irqchip = { | 269 | static struct irq_chip crystalcove_irqchip = { |