1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * Driver for Allwinner sunXi IR controller 4 * 5 * Copyright (C) 2014 Alexsey Shestacov <wingrime@linux-sunxi.org> 6 * Copyright (C) 2014 Alexander Bersenev <bay@hackerdom.ru> 7 * 8 * Based on sun5i-ir.c: 9 * Copyright (C) 2007-2012 Daniel Wang 10 * Allwinner Technology Co., Ltd. <www.allwinnertech.com> 11 */ 12 13 #include <linux/clk.h> 14 #include <linux/interrupt.h> 15 #include <linux/module.h> 16 #include <linux/of.h> 17 #include <linux/platform_device.h> 18 #include <linux/reset.h> 19 #include <media/rc-core.h> 20 21 #define SUNXI_IR_DEV "sunxi-ir" 22 23 /* Registers */ 24 /* IR Control */ 25 #define SUNXI_IR_CTL_REG 0x00 26 /* Global Enable */ 27 #define REG_CTL_GEN BIT(0) 28 /* RX block enable */ 29 #define REG_CTL_RXEN BIT(1) 30 /* CIR mode */ 31 #define REG_CTL_MD (BIT(4) | BIT(5)) 32 33 /* Rx Config */ 34 #define SUNXI_IR_RXCTL_REG 0x10 35 /* Pulse Polarity Invert flag */ 36 #define REG_RXCTL_RPPI BIT(2) 37 38 /* Rx Data */ 39 #define SUNXI_IR_RXFIFO_REG 0x20 40 41 /* Rx Interrupt Enable */ 42 #define SUNXI_IR_RXINT_REG 0x2C 43 /* Rx FIFO Overflow Interrupt Enable */ 44 #define REG_RXINT_ROI_EN BIT(0) 45 /* Rx Packet End Interrupt Enable */ 46 #define REG_RXINT_RPEI_EN BIT(1) 47 /* Rx FIFO Data Available Interrupt Enable */ 48 #define REG_RXINT_RAI_EN BIT(4) 49 50 /* Rx FIFO available byte level */ 51 #define REG_RXINT_RAL(val) ((val) << 8) 52 53 /* Rx Interrupt Status */ 54 #define SUNXI_IR_RXSTA_REG 0x30 55 /* Rx FIFO Overflow */ 56 #define REG_RXSTA_ROI REG_RXINT_ROI_EN 57 /* Rx Packet End */ 58 #define REG_RXSTA_RPE REG_RXINT_RPEI_EN 59 /* Rx FIFO Data Available */ 60 #define REG_RXSTA_RA REG_RXINT_RAI_EN 61 /* RX FIFO Get Available Counter */ 62 #define REG_RXSTA_GET_AC(val) (((val) >> 8) & (ir->fifo_size * 2 - 1)) 63 /* Clear all interrupt status value */ 64 #define REG_RXSTA_CLEARALL 0xff 65 66 /* IR Sample Config */ 67 #define SUNXI_IR_CIR_REG 0x34 68 /* CIR_REG register noise threshold */ 69 #define REG_CIR_NTHR(val) (((val) << 2) & (GENMASK(7, 2))) 70 /* CIR_REG register idle threshold */ 71 #define REG_CIR_ITHR(val) (((val) << 8) & (GENMASK(15, 8))) 72 73 /* Required frequency for IR0 or IR1 clock in CIR mode (default) */ 74 #define SUNXI_IR_BASE_CLK 8000000 75 /* Noise threshold in samples */ 76 #define SUNXI_IR_RXNOISE 1 77 78 /** 79 * struct sunxi_ir_quirks - Differences between SoC variants. 80 * 81 * @has_reset: SoC needs reset deasserted. 82 * @fifo_size: size of the fifo. 83 */ 84 struct sunxi_ir_quirks { 85 bool has_reset; 86 int fifo_size; 87 }; 88 89 struct sunxi_ir { 90 struct rc_dev *rc; 91 void __iomem *base; 92 int irq; 93 int fifo_size; 94 struct clk *clk; 95 struct clk *apb_clk; 96 struct reset_control *rst; 97 const char *map_name; 98 }; 99 100 static irqreturn_t sunxi_ir_irq(int irqno, void *dev_id) 101 { 102 unsigned long status; 103 unsigned char dt; 104 unsigned int cnt, rc; 105 struct sunxi_ir *ir = dev_id; 106 struct ir_raw_event rawir = {}; 107 108 status = readl(ir->base + SUNXI_IR_RXSTA_REG); 109 110 /* clean all pending statuses */ 111 writel(status | REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); 112 113 if (status & (REG_RXSTA_RA | REG_RXSTA_RPE)) { 114 /* How many messages in fifo */ 115 rc = REG_RXSTA_GET_AC(status); 116 /* Sanity check */ 117 rc = rc > ir->fifo_size ? ir->fifo_size : rc; 118 /* If we have data */ 119 for (cnt = 0; cnt < rc; cnt++) { 120 /* for each bit in fifo */ 121 dt = readb(ir->base + SUNXI_IR_RXFIFO_REG); 122 rawir.pulse = (dt & 0x80) != 0; 123 rawir.duration = ((dt & 0x7f) + 1) * 124 ir->rc->rx_resolution; 125 ir_raw_event_store_with_filter(ir->rc, &rawir); 126 } 127 } 128 129 if (status & REG_RXSTA_ROI) { 130 ir_raw_event_overflow(ir->rc); 131 } else if (status & REG_RXSTA_RPE) { 132 ir_raw_event_set_idle(ir->rc, true); 133 ir_raw_event_handle(ir->rc); 134 } else { 135 ir_raw_event_handle(ir->rc); 136 } 137 138 return IRQ_HANDLED; 139 } 140 141 /* Convert idle threshold to usec */ 142 static unsigned int sunxi_ithr_to_usec(unsigned int base_clk, unsigned int ithr) 143 { 144 return DIV_ROUND_CLOSEST(USEC_PER_SEC * (ithr + 1), 145 base_clk / (128 * 64)); 146 } 147 148 /* Convert usec to idle threshold */ 149 static unsigned int sunxi_usec_to_ithr(unsigned int base_clk, unsigned int usec) 150 { 151 /* make sure we don't end up with a timeout less than requested */ 152 return DIV_ROUND_UP((base_clk / (128 * 64)) * usec, USEC_PER_SEC) - 1; 153 } 154 155 static int sunxi_ir_set_timeout(struct rc_dev *rc_dev, unsigned int timeout) 156 { 157 struct sunxi_ir *ir = rc_dev->priv; 158 unsigned int base_clk = clk_get_rate(ir->clk); 159 160 unsigned int ithr = sunxi_usec_to_ithr(base_clk, timeout); 161 162 dev_dbg(rc_dev->dev.parent, "setting idle threshold to %u\n", ithr); 163 164 /* Set noise threshold and idle threshold */ 165 writel(REG_CIR_NTHR(SUNXI_IR_RXNOISE) | REG_CIR_ITHR(ithr), 166 ir->base + SUNXI_IR_CIR_REG); 167 168 rc_dev->timeout = sunxi_ithr_to_usec(base_clk, ithr); 169 170 return 0; 171 } 172 173 static int sunxi_ir_hw_init(struct device *dev) 174 { 175 struct sunxi_ir *ir = dev_get_drvdata(dev); 176 u32 tmp; 177 int ret; 178 179 ret = reset_control_deassert(ir->rst); 180 if (ret) 181 return ret; 182 183 ret = clk_prepare_enable(ir->apb_clk); 184 if (ret) { 185 dev_err(dev, "failed to enable apb clk\n"); 186 goto exit_assert_reset; 187 } 188 189 ret = clk_prepare_enable(ir->clk); 190 if (ret) { 191 dev_err(dev, "failed to enable ir clk\n"); 192 goto exit_disable_apb_clk; 193 } 194 195 /* Enable CIR Mode */ 196 writel(REG_CTL_MD, ir->base + SUNXI_IR_CTL_REG); 197 198 /* Set noise threshold and idle threshold */ 199 sunxi_ir_set_timeout(ir->rc, ir->rc->timeout); 200 201 /* Invert Input Signal */ 202 writel(REG_RXCTL_RPPI, ir->base + SUNXI_IR_RXCTL_REG); 203 204 /* Clear All Rx Interrupt Status */ 205 writel(REG_RXSTA_CLEARALL, ir->base + SUNXI_IR_RXSTA_REG); 206 207 /* 208 * Enable IRQ on overflow, packet end, FIFO available with trigger 209 * level 210 */ 211 writel(REG_RXINT_ROI_EN | REG_RXINT_RPEI_EN | 212 REG_RXINT_RAI_EN | REG_RXINT_RAL(ir->fifo_size / 2 - 1), 213 ir->base + SUNXI_IR_RXINT_REG); 214 215 /* Enable IR Module */ 216 tmp = readl(ir->base + SUNXI_IR_CTL_REG); 217 writel(tmp | REG_CTL_GEN | REG_CTL_RXEN, ir->base + SUNXI_IR_CTL_REG); 218 219 return 0; 220 221 exit_disable_apb_clk: 222 clk_disable_unprepare(ir->apb_clk); 223 exit_assert_reset: 224 reset_control_assert(ir->rst); 225 226 return ret; 227 } 228 229 static void sunxi_ir_hw_exit(struct device *dev) 230 { 231 struct sunxi_ir *ir = dev_get_drvdata(dev); 232 233 clk_disable_unprepare(ir->clk); 234 clk_disable_unprepare(ir->apb_clk); 235 reset_control_assert(ir->rst); 236 } 237 238 static int __maybe_unused sunxi_ir_suspend(struct device *dev) 239 { 240 sunxi_ir_hw_exit(dev); 241 242 return 0; 243 } 244 245 static int __maybe_unused sunxi_ir_resume(struct device *dev) 246 { 247 return sunxi_ir_hw_init(dev); 248 } 249 250 static SIMPLE_DEV_PM_OPS(sunxi_ir_pm_ops, sunxi_ir_suspend, sunxi_ir_resume); 251 252 static int sunxi_ir_probe(struct platform_device *pdev) 253 { 254 int ret = 0; 255 256 struct device *dev = &pdev->dev; 257 struct device_node *dn = dev->of_node; 258 const struct sunxi_ir_quirks *quirks; 259 struct sunxi_ir *ir; 260 u32 b_clk_freq = SUNXI_IR_BASE_CLK; 261 262 ir = devm_kzalloc(dev, sizeof(struct sunxi_ir), GFP_KERNEL); 263 if (!ir) 264 return -ENOMEM; 265 266 quirks = of_device_get_match_data(&pdev->dev); 267 if (!quirks) { 268 dev_err(&pdev->dev, "Failed to determine the quirks to use\n"); 269 return -ENODEV; 270 } 271 272 ir->fifo_size = quirks->fifo_size; 273 274 /* Clock */ 275 ir->apb_clk = devm_clk_get(dev, "apb"); 276 if (IS_ERR(ir->apb_clk)) { 277 dev_err(dev, "failed to get a apb clock.\n"); 278 return PTR_ERR(ir->apb_clk); 279 } 280 ir->clk = devm_clk_get(dev, "ir"); 281 if (IS_ERR(ir->clk)) { 282 dev_err(dev, "failed to get a ir clock.\n"); 283 return PTR_ERR(ir->clk); 284 } 285 286 /* Base clock frequency (optional) */ 287 of_property_read_u32(dn, "clock-frequency", &b_clk_freq); 288 289 /* Reset */ 290 if (quirks->has_reset) { 291 ir->rst = devm_reset_control_get_exclusive(dev, NULL); 292 if (IS_ERR(ir->rst)) 293 return PTR_ERR(ir->rst); 294 } 295 296 ret = clk_set_rate(ir->clk, b_clk_freq); 297 if (ret) { 298 dev_err(dev, "set ir base clock failed!\n"); 299 return ret; 300 } 301 dev_dbg(dev, "set base clock frequency to %d Hz.\n", b_clk_freq); 302 303 /* IO */ 304 ir->base = devm_platform_ioremap_resource(pdev, 0); 305 if (IS_ERR(ir->base)) { 306 return PTR_ERR(ir->base); 307 } 308 309 ir->rc = rc_allocate_device(RC_DRIVER_IR_RAW); 310 if (!ir->rc) { 311 dev_err(dev, "failed to allocate device\n"); 312 return -ENOMEM; 313 } 314 315 ir->rc->priv = ir; 316 ir->rc->device_name = SUNXI_IR_DEV; 317 ir->rc->input_phys = "sunxi-ir/input0"; 318 ir->rc->input_id.bustype = BUS_HOST; 319 ir->rc->input_id.vendor = 0x0001; 320 ir->rc->input_id.product = 0x0001; 321 ir->rc->input_id.version = 0x0100; 322 ir->map_name = of_get_property(dn, "linux,rc-map-name", NULL); 323 ir->rc->map_name = ir->map_name ?: RC_MAP_EMPTY; 324 ir->rc->dev.parent = dev; 325 ir->rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; 326 /* Frequency after IR internal divider with sample period in us */ 327 ir->rc->rx_resolution = (USEC_PER_SEC / (b_clk_freq / 64)); 328 ir->rc->timeout = IR_DEFAULT_TIMEOUT; 329 ir->rc->min_timeout = sunxi_ithr_to_usec(b_clk_freq, 0); 330 ir->rc->max_timeout = sunxi_ithr_to_usec(b_clk_freq, 255); 331 ir->rc->s_timeout = sunxi_ir_set_timeout; 332 ir->rc->driver_name = SUNXI_IR_DEV; 333 334 ret = rc_register_device(ir->rc); 335 if (ret) { 336 dev_err(dev, "failed to register rc device\n"); 337 goto exit_free_dev; 338 } 339 340 platform_set_drvdata(pdev, ir); 341 342 /* IRQ */ 343 ir->irq = platform_get_irq(pdev, 0); 344 if (ir->irq < 0) { 345 ret = ir->irq; 346 goto exit_free_dev; 347 } 348 349 ret = devm_request_irq(dev, ir->irq, sunxi_ir_irq, 0, SUNXI_IR_DEV, ir); 350 if (ret) { 351 dev_err(dev, "failed request irq\n"); 352 goto exit_free_dev; 353 } 354 355 ret = sunxi_ir_hw_init(dev); 356 if (ret) 357 goto exit_free_dev; 358 359 dev_info(dev, "initialized sunXi IR driver\n"); 360 return 0; 361 362 exit_free_dev: 363 rc_free_device(ir->rc); 364 365 return ret; 366 } 367 368 static void sunxi_ir_remove(struct platform_device *pdev) 369 { 370 struct sunxi_ir *ir = platform_get_drvdata(pdev); 371 372 rc_unregister_device(ir->rc); 373 sunxi_ir_hw_exit(&pdev->dev); 374 } 375 376 static void sunxi_ir_shutdown(struct platform_device *pdev) 377 { 378 sunxi_ir_hw_exit(&pdev->dev); 379 } 380 381 static const struct sunxi_ir_quirks sun4i_a10_ir_quirks = { 382 .has_reset = false, 383 .fifo_size = 16, 384 }; 385 386 static const struct sunxi_ir_quirks sun5i_a13_ir_quirks = { 387 .has_reset = false, 388 .fifo_size = 64, 389 }; 390 391 static const struct sunxi_ir_quirks sun6i_a31_ir_quirks = { 392 .has_reset = true, 393 .fifo_size = 64, 394 }; 395 396 static const struct of_device_id sunxi_ir_match[] = { 397 { 398 .compatible = "allwinner,sun4i-a10-ir", 399 .data = &sun4i_a10_ir_quirks, 400 }, 401 { 402 .compatible = "allwinner,sun5i-a13-ir", 403 .data = &sun5i_a13_ir_quirks, 404 }, 405 { 406 .compatible = "allwinner,sun6i-a31-ir", 407 .data = &sun6i_a31_ir_quirks, 408 }, 409 {} 410 }; 411 MODULE_DEVICE_TABLE(of, sunxi_ir_match); 412 413 static struct platform_driver sunxi_ir_driver = { 414 .probe = sunxi_ir_probe, 415 .remove_new = sunxi_ir_remove, 416 .shutdown = sunxi_ir_shutdown, 417 .driver = { 418 .name = SUNXI_IR_DEV, 419 .of_match_table = sunxi_ir_match, 420 .pm = &sunxi_ir_pm_ops, 421 }, 422 }; 423 424 module_platform_driver(sunxi_ir_driver); 425 426 MODULE_DESCRIPTION("Allwinner sunXi IR controller driver"); 427 MODULE_AUTHOR("Alexsey Shestacov <wingrime@linux-sunxi.org>"); 428 MODULE_LICENSE("GPL"); 429