Lines Matching +full:hix5hd2 +full:- +full:clock

1 // SPDX-License-Identifier: GPL-2.0-only
14 #include <media/rc-core.h>
62 #define IR_HIX5HD2_NAME "hix5hd2-ir"
87 struct clk *clock; member
94 u32 clk_reg = dev->socdata->clk_reg; in hix5hd2_ir_clk_enable()
98 if (dev->regmap) { in hix5hd2_ir_clk_enable()
99 regmap_read(dev->regmap, clk_reg, &val); in hix5hd2_ir_clk_enable()
107 regmap_write(dev->regmap, clk_reg, val); in hix5hd2_ir_clk_enable()
110 ret = clk_prepare_enable(dev->clock); in hix5hd2_ir_clk_enable()
112 clk_disable_unprepare(dev->clock); in hix5hd2_ir_clk_enable()
121 if (priv->socdata->flags & HIX5HD2_FLAG_EXTRA_ENABLE) in hix5hd2_ir_enable()
124 writel_relaxed(val, priv->base + IR_ENABLE); in hix5hd2_ir_enable()
134 while (readl_relaxed(priv->base + IR_BUSY)) { in hix5hd2_ir_config()
135 if (timeout--) { in hix5hd2_ir_config()
138 dev_err(priv->dev, "IR_BUSY timeout\n"); in hix5hd2_ir_config()
139 return -ETIMEDOUT; in hix5hd2_ir_config()
144 rate = DIV_ROUND_CLOSEST(priv->rate, 1000000); in hix5hd2_ir_config()
147 val |= (IR_CFG_INT_THRESHOLD - 1) & IR_CFG_INT_LEVEL_MASK in hix5hd2_ir_config()
150 val |= (rate - 1) & IR_CFG_FREQ_MASK << IR_CFG_FREQ_SHIFT; in hix5hd2_ir_config()
151 writel_relaxed(val, priv->base + IR_CONFIG); in hix5hd2_ir_config()
153 writel_relaxed(0x00, priv->base + IR_INTM); in hix5hd2_ir_config()
155 writel_relaxed(0x01, priv->base + IR_START); in hix5hd2_ir_config()
161 struct hix5hd2_ir_priv *priv = rdev->priv; in hix5hd2_ir_open()
178 struct hix5hd2_ir_priv *priv = rdev->priv; in hix5hd2_ir_close()
190 irq_sr = readl_relaxed(priv->base + IR_INTS); in hix5hd2_ir_rx_interrupt()
197 ir_raw_event_overflow(priv->rdev); in hix5hd2_ir_rx_interrupt()
198 symb_num = readl_relaxed(priv->base + IR_DATAH); in hix5hd2_ir_rx_interrupt()
200 readl_relaxed(priv->base + IR_DATAL); in hix5hd2_ir_rx_interrupt()
202 writel_relaxed(INT_CLR_OVERFLOW, priv->base + IR_INTC); in hix5hd2_ir_rx_interrupt()
203 dev_info(priv->dev, "overflow, level=%d\n", in hix5hd2_ir_rx_interrupt()
210 symb_num = readl_relaxed(priv->base + IR_DATAH); in hix5hd2_ir_rx_interrupt()
212 symb_val = readl_relaxed(priv->base + IR_DATAL); in hix5hd2_ir_rx_interrupt()
219 ir_raw_event_store(priv->rdev, &ev); in hix5hd2_ir_rx_interrupt()
224 ir_raw_event_store(priv->rdev, &ev); in hix5hd2_ir_rx_interrupt()
226 ir_raw_event_set_idle(priv->rdev, true); in hix5hd2_ir_rx_interrupt()
231 writel_relaxed(INT_CLR_RCV, priv->base + IR_INTC); in hix5hd2_ir_rx_interrupt()
233 writel_relaxed(INT_CLR_TIMEOUT, priv->base + IR_INTC); in hix5hd2_ir_rx_interrupt()
237 ir_raw_event_handle(priv->rdev); in hix5hd2_ir_rx_interrupt()
242 { .compatible = "hisilicon,hix5hd2-ir", &hix5hd2_data, },
243 { .compatible = "hisilicon,hi3796cv300-ir", &hi3796cv300_data, },
251 struct device *dev = &pdev->dev; in hix5hd2_ir_probe()
253 struct device_node *node = pdev->dev.of_node; in hix5hd2_ir_probe()
260 return -ENOMEM; in hix5hd2_ir_probe()
265 return -ENODEV; in hix5hd2_ir_probe()
267 priv->socdata = of_id->data; in hix5hd2_ir_probe()
269 priv->regmap = syscon_regmap_lookup_by_phandle(node, in hix5hd2_ir_probe()
270 "hisilicon,power-syscon"); in hix5hd2_ir_probe()
271 if (IS_ERR(priv->regmap)) { in hix5hd2_ir_probe()
272 dev_info(dev, "no power-reg\n"); in hix5hd2_ir_probe()
273 priv->regmap = NULL; in hix5hd2_ir_probe()
276 priv->base = devm_platform_ioremap_resource(pdev, 0); in hix5hd2_ir_probe()
277 if (IS_ERR(priv->base)) in hix5hd2_ir_probe()
278 return PTR_ERR(priv->base); in hix5hd2_ir_probe()
280 priv->irq = platform_get_irq(pdev, 0); in hix5hd2_ir_probe()
281 if (priv->irq < 0) in hix5hd2_ir_probe()
282 return priv->irq; in hix5hd2_ir_probe()
286 return -ENOMEM; in hix5hd2_ir_probe()
288 priv->clock = devm_clk_get(dev, NULL); in hix5hd2_ir_probe()
289 if (IS_ERR(priv->clock)) { in hix5hd2_ir_probe()
290 dev_err(dev, "clock not found\n"); in hix5hd2_ir_probe()
291 ret = PTR_ERR(priv->clock); in hix5hd2_ir_probe()
294 ret = clk_prepare_enable(priv->clock); in hix5hd2_ir_probe()
297 priv->rate = clk_get_rate(priv->clock); in hix5hd2_ir_probe()
299 rdev->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER; in hix5hd2_ir_probe()
300 rdev->priv = priv; in hix5hd2_ir_probe()
301 rdev->open = hix5hd2_ir_open; in hix5hd2_ir_probe()
302 rdev->close = hix5hd2_ir_close; in hix5hd2_ir_probe()
303 rdev->driver_name = IR_HIX5HD2_NAME; in hix5hd2_ir_probe()
304 map_name = of_get_property(node, "linux,rc-map-name", NULL); in hix5hd2_ir_probe()
305 rdev->map_name = map_name ?: RC_MAP_EMPTY; in hix5hd2_ir_probe()
306 rdev->device_name = IR_HIX5HD2_NAME; in hix5hd2_ir_probe()
307 rdev->input_phys = IR_HIX5HD2_NAME "/input0"; in hix5hd2_ir_probe()
308 rdev->input_id.bustype = BUS_HOST; in hix5hd2_ir_probe()
309 rdev->input_id.vendor = 0x0001; in hix5hd2_ir_probe()
310 rdev->input_id.product = 0x0001; in hix5hd2_ir_probe()
311 rdev->input_id.version = 0x0100; in hix5hd2_ir_probe()
312 rdev->rx_resolution = 10; in hix5hd2_ir_probe()
313 rdev->timeout = IR_CFG_SYMBOL_MAXWIDTH * 10; in hix5hd2_ir_probe()
319 if (devm_request_irq(dev, priv->irq, hix5hd2_ir_rx_interrupt, in hix5hd2_ir_probe()
320 0, pdev->name, priv) < 0) { in hix5hd2_ir_probe()
321 dev_err(dev, "IRQ %d register failed\n", priv->irq); in hix5hd2_ir_probe()
322 ret = -EINVAL; in hix5hd2_ir_probe()
326 priv->rdev = rdev; in hix5hd2_ir_probe()
327 priv->dev = dev; in hix5hd2_ir_probe()
336 clk_disable_unprepare(priv->clock); in hix5hd2_ir_probe()
347 clk_disable_unprepare(priv->clock); in hix5hd2_ir_remove()
348 rc_unregister_device(priv->rdev); in hix5hd2_ir_remove()
356 clk_disable_unprepare(priv->clock); in hix5hd2_ir_suspend()
371 ret = clk_prepare_enable(priv->clock); in hix5hd2_ir_resume()
379 writel_relaxed(0x00, priv->base + IR_INTM); in hix5hd2_ir_resume()
380 writel_relaxed(0xff, priv->base + IR_INTC); in hix5hd2_ir_resume()
381 writel_relaxed(0x01, priv->base + IR_START); in hix5hd2_ir_resume()
402 MODULE_DESCRIPTION("IR controller driver for hix5hd2 platforms");
405 MODULE_ALIAS("platform:hix5hd2-ir");