xref: /OK3568_Linux_fs/kernel/drivers/mfd/rk628.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (C) 2020 Rockchip Electronics Co. Ltd.
4  *
5  * Author: Wyon Bi <bivvy.bi@rock-chips.com>
6  */
7 
8 #include <linux/module.h>
9 #include <linux/init.h>
10 #include <linux/interrupt.h>
11 #include <linux/i2c.h>
12 #include <linux/gpio/consumer.h>
13 #include <linux/regmap.h>
14 #include <linux/mfd/core.h>
15 #include <linux/mfd/rk628.h>
16 
17 enum {
18 	RK628_IRQ_HDMITX_HPD_HIGH,
19 	RK628_IRQ_HDMITX_HPD_LOW,
20 	RK628_IRQ_HDMITX,
21 	RK628_IRQ_GVI,
22 	RK628_IRQ_DSI1,
23 	RK628_IRQ_DSI0,
24 	RK628_IRQ_CSI,
25 	RK628_IRQ_HDMIRX,
26 
27 	RK628_IRQ_GPIO0,
28 	RK628_IRQ_GPIO1,
29 	RK628_IRQ_GPIO2,
30 	RK628_IRQ_GPIO3,
31 	RK628_IRQ_EFUSE,
32 };
33 
34 static struct resource rk628_gpio_resources[] = {
35 	DEFINE_RES_IRQ(RK628_IRQ_GPIO0),
36 	DEFINE_RES_IRQ(RK628_IRQ_GPIO1),
37 	DEFINE_RES_IRQ(RK628_IRQ_GPIO2),
38 	DEFINE_RES_IRQ(RK628_IRQ_GPIO3),
39 };
40 
41 static struct resource rk628_dsi0_resources[] = {
42 	DEFINE_RES_IRQ(RK628_IRQ_DSI0),
43 };
44 
45 static struct resource rk628_dsi1_resources[] = {
46 	DEFINE_RES_IRQ(RK628_IRQ_DSI1),
47 };
48 
49 static struct resource rk628_csi_resources[] = {
50 	DEFINE_RES_IRQ(RK628_IRQ_CSI),
51 	DEFINE_RES_IRQ(RK628_IRQ_HDMIRX),
52 };
53 
54 static struct resource rk628_gvi_resources[] = {
55 	DEFINE_RES_IRQ(RK628_IRQ_GVI),
56 };
57 
58 static struct resource rk628_hdmi_resources[] = {
59 	DEFINE_RES_IRQ(RK628_IRQ_HDMITX),
60 	DEFINE_RES_IRQ(RK628_IRQ_HDMITX_HPD_HIGH),
61 	DEFINE_RES_IRQ(RK628_IRQ_HDMITX_HPD_LOW),
62 };
63 
64 static struct resource rk628_hdmirx_resources[] = {
65 	DEFINE_RES_IRQ(RK628_IRQ_HDMIRX),
66 };
67 
68 static struct resource rk628_efuse_resources[] = {
69 	DEFINE_RES_IRQ(RK628_IRQ_EFUSE),
70 };
71 
72 static const struct mfd_cell rk628_devs[] = {
73 	{
74 		.name = "rk628-cru",
75 		.of_compatible = "rockchip,rk628-cru",
76 	}, {
77 		.name = "rk628-pinctrl",
78 		.of_compatible = "rockchip,rk628-pinctrl",
79 		.resources = rk628_gpio_resources,
80 		.num_resources = ARRAY_SIZE(rk628_gpio_resources),
81 	}, {
82 		.name = "rk628-combrxphy",
83 		.of_compatible = "rockchip,rk628-combrxphy",
84 	}, {
85 		.name = "rk628-combtxphy",
86 		.of_compatible = "rockchip,rk628-combtxphy",
87 	}, {
88 		.name = "rk628-csi",
89 		.of_compatible = "rockchip,rk628-csi",
90 		.resources = rk628_csi_resources,
91 		.num_resources = ARRAY_SIZE(rk628_csi_resources),
92 	}, {
93 		.name = "rk628-hdmirx",
94 		.of_compatible = "rockchip,rk628-hdmirx",
95 		.resources = rk628_hdmirx_resources,
96 		.num_resources = ARRAY_SIZE(rk628_hdmirx_resources),
97 	}, {
98 		.name = "rk628-dsi1",
99 		.of_compatible = "rockchip,rk628-dsi1",
100 		.resources = rk628_dsi1_resources,
101 		.num_resources = ARRAY_SIZE(rk628_dsi1_resources),
102 	}, {
103 		.name = "rk628-dsi0",
104 		.of_compatible = "rockchip,rk628-dsi0",
105 		.resources = rk628_dsi0_resources,
106 		.num_resources = ARRAY_SIZE(rk628_dsi0_resources),
107 	}, {
108 		.name = "rk628-rgb-tx",
109 		.of_compatible = "rockchip,rk628-rgb-tx",
110 	}, {
111 		.name = "rk628-yuv-rx",
112 		.of_compatible = "rockchip,rk628-yuv-rx",
113 	}, {
114 		.name = "rk628-yuv-tx",
115 		.of_compatible = "rockchip,rk628-yuv-tx",
116 	}, {
117 		.name = "rk628-bt1120-rx",
118 		.of_compatible = "rockchip,rk628-bt1120-rx",
119 	}, {
120 		.name = "rk628-bt1120-tx",
121 		.of_compatible = "rockchip,rk628-bt1120-tx",
122 	}, {
123 		.name = "rk628-lvds",
124 		.of_compatible = "rockchip,rk628-lvds",
125 	}, {
126 		.name = "rk628-gvi",
127 		.of_compatible = "rockchip,rk628-gvi",
128 		.resources = rk628_gvi_resources,
129 		.num_resources = ARRAY_SIZE(rk628_gvi_resources),
130 	}, {
131 		.name = "rk628-hdmi",
132 		.of_compatible = "rockchip,rk628-hdmi",
133 		.resources = rk628_hdmi_resources,
134 		.num_resources = ARRAY_SIZE(rk628_hdmi_resources),
135 	}, {
136 		.name = "rk628-efuse",
137 		.of_compatible = "rockchip,rk628-efuse",
138 		.resources = rk628_efuse_resources,
139 		.num_resources = ARRAY_SIZE(rk628_efuse_resources),
140 	}, {
141 		.name = "rk628-post-process",
142 		.of_compatible = "rockchip,rk628-post-process",
143 	},
144 };
145 
146 static const struct regmap_irq rk628_irqs[] = {
147 	REGMAP_IRQ_REG(RK628_IRQ_HDMITX_HPD_HIGH, 0, BIT(0)),
148 	REGMAP_IRQ_REG(RK628_IRQ_HDMITX_HPD_LOW, 0, BIT(1)),
149 	REGMAP_IRQ_REG(RK628_IRQ_HDMITX, 0, BIT(2)),
150 	REGMAP_IRQ_REG(RK628_IRQ_GVI, 0, BIT(3)),
151 	REGMAP_IRQ_REG(RK628_IRQ_DSI1, 0, BIT(4)),
152 	REGMAP_IRQ_REG(RK628_IRQ_DSI0, 0, BIT(5)),
153 	REGMAP_IRQ_REG(RK628_IRQ_CSI, 0, BIT(6)),
154 	REGMAP_IRQ_REG(RK628_IRQ_HDMIRX, 0, BIT(8)),
155 
156 	REGMAP_IRQ_REG(RK628_IRQ_GPIO0, 4, BIT(0)),
157 	REGMAP_IRQ_REG(RK628_IRQ_GPIO1, 4, BIT(1)),
158 	REGMAP_IRQ_REG(RK628_IRQ_GPIO2, 4, BIT(2)),
159 	REGMAP_IRQ_REG(RK628_IRQ_GPIO3, 4, BIT(3)),
160 	REGMAP_IRQ_REG(RK628_IRQ_EFUSE, 4, BIT(4)),
161 };
162 
163 static struct rk628_irq_chip_data rk628_irq_chip_data = {
164 	.name = "rk628",
165 	.irqs = rk628_irqs,
166 	.num_irqs = ARRAY_SIZE(rk628_irqs),
167 	.num_regs = 2,
168 	.irq_reg_stride = (GRF_INTR1_STATUS - GRF_INTR0_STATUS) / 4,
169 	.reg_stride = 4,
170 	.status_base = GRF_INTR0_STATUS,
171 	.mask_base = GRF_INTR0_EN,
172 	.ack_base = GRF_INTR0_CLR_EN,
173 };
174 
175 static const struct regmap_config rk628_grf_regmap_config = {
176 	.name = "grf",
177 	.reg_bits = 32,
178 	.val_bits = 32,
179 	.reg_stride = 4,
180 	.max_register = GRF_MAX_REGISTER,
181 	.reg_format_endian = REGMAP_ENDIAN_LITTLE,
182 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
183 };
184 
185 static inline const struct regmap_irq *
irq_to_regmap_irq(struct rk628_irq_chip_data * d,int irq)186 irq_to_regmap_irq(struct rk628_irq_chip_data *d, int irq)
187 {
188 	return &d->irqs[irq];
189 }
190 
rk628_irq_lock(struct irq_data * data)191 static void rk628_irq_lock(struct irq_data *data)
192 {
193 	struct rk628_irq_chip_data *d = irq_data_get_irq_chip_data(data);
194 
195 	mutex_lock(&d->lock);
196 }
197 
rk628_irq_sync_unlock(struct irq_data * data)198 static void rk628_irq_sync_unlock(struct irq_data *data)
199 {
200 	struct rk628_irq_chip_data *d = irq_data_get_irq_chip_data(data);
201 	int i;
202 	u32 reg, mask, val;
203 
204 	for (i = 0; i < d->num_regs; i++) {
205 		reg = d->mask_base + (i * d->reg_stride * d->irq_reg_stride);
206 		mask = d->mask_buf_def[i];
207 		val = mask << 16 | (~d->mask_buf[i] & mask);
208 		regmap_write(d->map, reg, val);
209 	}
210 
211 	mutex_unlock(&d->lock);
212 }
213 
rk628_irq_enable(struct irq_data * data)214 static void rk628_irq_enable(struct irq_data *data)
215 {
216 	struct rk628_irq_chip_data *d = irq_data_get_irq_chip_data(data);
217 	const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
218 
219 	d->mask_buf[irq_data->reg_offset / d->reg_stride] &= ~irq_data->mask;
220 }
221 
rk628_irq_disable(struct irq_data * data)222 static void rk628_irq_disable(struct irq_data *data)
223 {
224 	struct rk628_irq_chip_data *d = irq_data_get_irq_chip_data(data);
225 	const struct regmap_irq *irq_data = irq_to_regmap_irq(d, data->hwirq);
226 
227 	d->mask_buf[irq_data->reg_offset / d->reg_stride] |= irq_data->mask;
228 }
229 
230 static const struct irq_chip rk628_irq_chip = {
231 	.irq_bus_lock = rk628_irq_lock,
232 	.irq_bus_sync_unlock = rk628_irq_sync_unlock,
233 	.irq_disable = rk628_irq_disable,
234 	.irq_enable = rk628_irq_enable,
235 };
236 
rk628_irq_thread(int irq,void * data)237 static irqreturn_t rk628_irq_thread(int irq, void *data)
238 {
239 	struct rk628_irq_chip_data *d = data;
240 	int i;
241 	bool handled = false;
242 	u32 reg;
243 
244 	for (i = 0; i < d->num_regs; i++) {
245 		reg = d->status_base + (i * d->reg_stride * d->irq_reg_stride);
246 		regmap_read(d->map, reg, &d->status_buf[i]);
247 	}
248 
249 	for (i = 0; i < d->num_irqs; i++) {
250 		if (d->status_buf[d->irqs[i].reg_offset / d->reg_stride] & d->irqs[i].mask) {
251 			handle_nested_irq(irq_find_mapping(d->domain, i));
252 			handled = true;
253 		}
254 	}
255 
256 	for (i = 0; i < d->num_regs; i++) {
257 		if (d->status_buf[i]) {
258 			reg = d->ack_base + (i * d->reg_stride * d->irq_reg_stride);
259 			regmap_write(d->map, reg,
260 				     d->status_buf[i] << 16 | d->status_buf[i]);
261 		}
262 	}
263 
264 	if (handled)
265 		return IRQ_HANDLED;
266 	else
267 		return IRQ_NONE;
268 }
269 
rk628_irq_map(struct irq_domain * h,unsigned int virq,irq_hw_number_t hw)270 static int rk628_irq_map(struct irq_domain *h, unsigned int virq,
271 			 irq_hw_number_t hw)
272 {
273 	struct rk628_irq_chip_data *d = h->host_data;
274 
275 	irq_set_chip_data(virq, d);
276 	irq_set_chip(virq, &d->irq_chip);
277 	irq_set_nested_thread(virq, 1);
278 	irq_set_parent(virq, d->irq);
279 	irq_set_noprobe(virq);
280 
281 	return 0;
282 }
283 
284 static const struct irq_domain_ops rk628_irq_domain_ops = {
285 	.map = rk628_irq_map,
286 	.xlate = irq_domain_xlate_onetwocell,
287 };
288 
rk628_irq_init(struct rk628 * rk628,int irq)289 static int rk628_irq_init(struct rk628 *rk628, int irq)
290 {
291 	struct device *dev = rk628->dev;
292 	struct rk628_irq_chip_data *d = rk628->irq_data;
293 	struct regmap *map = rk628->grf;
294 	u32 reg, mask, val;
295 	int i;
296 	int ret;
297 
298 	if (d->num_regs <= 0)
299 		return -EINVAL;
300 
301 	d->status_buf = devm_kcalloc(dev, d->num_regs, sizeof(unsigned int),
302 				     GFP_KERNEL);
303 	if (!d->status_buf)
304 		return -ENOMEM;
305 
306 	d->mask_buf = devm_kcalloc(dev, d->num_regs, sizeof(unsigned int),
307 				   GFP_KERNEL);
308 	if (!d->mask_buf)
309 		return -ENOMEM;
310 
311 	d->mask_buf_def = devm_kcalloc(dev, d->num_regs, sizeof(unsigned int),
312 				       GFP_KERNEL);
313 	if (!d->mask_buf_def)
314 		return -ENOMEM;
315 
316 	d->irq_chip = rk628_irq_chip;
317 	d->irq_chip.name = d->name;
318 	d->irq = irq;
319 	d->map = map;
320 
321 	mutex_init(&d->lock);
322 
323 	for (i = 0; i < d->num_irqs; i++)
324 		d->mask_buf_def[d->irqs[i].reg_offset / d->reg_stride] |= d->irqs[i].mask;
325 
326 	/* Mask all the interrupts by default */
327 	for (i = 0; i < d->num_regs; i++) {
328 		d->mask_buf[i] = d->mask_buf_def[i];
329 		reg = d->mask_base + (i * d->reg_stride * d->irq_reg_stride);
330 		mask = d->mask_buf[i];
331 		val = mask << 16 | (~d->mask_buf[i] & mask);
332 		regmap_write(d->map, reg, val);
333 	}
334 
335 	d->domain = irq_domain_add_linear(dev->of_node, d->num_irqs,
336 					  &rk628_irq_domain_ops, d);
337 	if (!d->domain) {
338 		dev_err(dev, "Failed to create IRQ domain\n");
339 		return -ENOMEM;
340 	}
341 
342 	ret = devm_request_threaded_irq(dev, irq, NULL, rk628_irq_thread,
343 					IRQF_ONESHOT, d->name, d);
344 	if (ret != 0) {
345 		irq_domain_remove(d->domain);
346 		dev_err(dev, "Failed to request IRQ %d: %d\n", irq, ret);
347 		return ret;
348 	}
349 
350 	return 0;
351 }
352 
rk628_irq_exit(struct rk628 * rk628)353 static void rk628_irq_exit(struct rk628 *rk628)
354 {
355 	struct rk628_irq_chip_data *d = rk628->irq_data;
356 	unsigned int virq;
357 	int hwirq;
358 
359 	/* Dispose all virtual irq from irq domain before removing it */
360 	for (hwirq = 0; hwirq < d->num_irqs; hwirq++) {
361 		/* Ignore hwirq if holes in the IRQ list */
362 		if (!d->irqs[hwirq].mask)
363 			continue;
364 
365 		/*
366 		 * Find the virtual irq of hwirq on chip and if it is
367 		 * there then dispose it
368 		 */
369 		virq = irq_find_mapping(d->domain, hwirq);
370 		if (virq)
371 			irq_dispose_mapping(virq);
372 	}
373 
374 	irq_domain_remove(d->domain);
375 }
376 
377 static int
rk628_i2c_probe(struct i2c_client * client,const struct i2c_device_id * id)378 rk628_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
379 {
380 	struct device *dev = &client->dev;
381 	struct rk628 *rk628;
382 	int ret;
383 
384 	rk628 = devm_kzalloc(dev, sizeof(*rk628), GFP_KERNEL);
385 	if (!rk628)
386 		return -ENOMEM;
387 
388 	rk628->dev = dev;
389 	rk628->client = client;
390 	rk628->irq_data = &rk628_irq_chip_data;
391 	i2c_set_clientdata(client, rk628);
392 
393 	rk628->enable_gpio = devm_gpiod_get_optional(dev, "enable",
394 						     GPIOD_OUT_LOW);
395 	if (IS_ERR(rk628->enable_gpio)) {
396 		ret = PTR_ERR(rk628->enable_gpio);
397 		dev_err(dev, "failed to request enable GPIO: %d\n", ret);
398 		return ret;
399 	}
400 
401 	rk628->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
402 	if (IS_ERR(rk628->reset_gpio)) {
403 		ret = PTR_ERR(rk628->reset_gpio);
404 		dev_err(dev, "failed to request reset GPIO: %d\n", ret);
405 		return ret;
406 	}
407 
408 	gpiod_set_value(rk628->enable_gpio, 1);
409 	usleep_range(10000, 11000);
410 	gpiod_set_value(rk628->reset_gpio, 0);
411 	usleep_range(10000, 11000);
412 	gpiod_set_value(rk628->reset_gpio, 1);
413 	usleep_range(10000, 11000);
414 	gpiod_set_value(rk628->reset_gpio, 0);
415 	usleep_range(10000, 11000);
416 
417 	rk628->grf = devm_regmap_init_i2c(client, &rk628_grf_regmap_config);
418 	if (IS_ERR(rk628->grf)) {
419 		ret = PTR_ERR(rk628->grf);
420 		dev_err(dev, "failed to allocate register map: %d\n", ret);
421 		return ret;
422 	}
423 
424 	/* selete int io function */
425 	ret = regmap_write(rk628->grf, GRF_GPIO3AB_SEL_CON, 0x30002000);
426 	if (ret) {
427 		dev_err(dev, "failed to access register: %d\n", ret);
428 		return ret;
429 	}
430 
431 	ret = rk628_irq_init(rk628, client->irq);
432 	if (ret) {
433 		dev_err(dev, "failed to add IRQ chip: %d\n", ret);
434 		return ret;
435 	}
436 
437 	ret = mfd_add_devices(dev, PLATFORM_DEVID_NONE,
438 			      rk628_devs, ARRAY_SIZE(rk628_devs),
439 			      NULL, 0, rk628->irq_data->domain);
440 	if (ret) {
441 		rk628_irq_exit(rk628);
442 		dev_err(dev, "Failed to add MFD children: %d\n", ret);
443 		return ret;
444 	}
445 
446 	return 0;
447 }
448 
rk628_i2c_remove(struct i2c_client * client)449 static int rk628_i2c_remove(struct i2c_client *client)
450 {
451 	struct rk628 *rk628 = i2c_get_clientdata(client);
452 
453 	mfd_remove_devices(rk628->dev);
454 	rk628_irq_exit(rk628);
455 
456 	return 0;
457 }
458 
459 static const struct of_device_id rk628_of_match[] = {
460 	{ .compatible = "rockchip,rk628", },
461 	{}
462 };
463 MODULE_DEVICE_TABLE(of, rk628_of_match);
464 
465 static const struct i2c_device_id rk628_i2c_id[] = {
466 	{ "rk628", 0 },
467 	{}
468 };
469 MODULE_DEVICE_TABLE(i2c, rk628_i2c_id);
470 
471 static struct i2c_driver rk628_i2c_driver = {
472 	.driver = {
473 		.name = "rk628",
474 		.of_match_table = of_match_ptr(rk628_of_match),
475 	},
476 	.probe = rk628_i2c_probe,
477 	.remove = rk628_i2c_remove,
478 	.id_table = rk628_i2c_id,
479 };
480 module_i2c_driver(rk628_i2c_driver);
481 
482 MODULE_AUTHOR("Wyon Bi <bivvy.bi@rock-chips.com>");
483 MODULE_DESCRIPTION("Rockchip RK628 MFD driver");
484 MODULE_LICENSE("GPL v2");
485