Lines Matching full:ir
3 * meson-ir-tx.c - Amlogic Meson IR TX driver
22 #define DEVICE_NAME "Meson IR TX"
23 #define DRIVER_NAME "meson-ir-tx"
79 static void meson_irtx_set_mod(struct meson_irtx *ir) in meson_irtx_set_mod() argument
81 unsigned int cnt = DIV_ROUND_CLOSEST(ir->clk_rate, ir->carrier); in meson_irtx_set_mod()
82 unsigned int pulse_cnt = DIV_ROUND_CLOSEST(cnt * ir->duty_cycle, 100); in meson_irtx_set_mod()
85 dev_dbg(ir->dev, "F_mod = %uHz, T_mod = %luns, duty_cycle = %u%%\n", in meson_irtx_set_mod()
86 ir->carrier, NSEC_PER_SEC / ir->clk_rate * cnt, in meson_irtx_set_mod()
90 ir->reg_base + IRB_ADDR1); in meson_irtx_set_mod()
93 static void meson_irtx_setup(struct meson_irtx *ir, unsigned int clk_nr) in meson_irtx_setup() argument
102 ir->reg_base + IRB_ADDR0); in meson_irtx_setup()
103 meson_irtx_set_mod(ir); in meson_irtx_setup()
104 writel(readl(ir->reg_base + IRB_ADDR0) & ~IRB_INIT_HIGH, in meson_irtx_setup()
105 ir->reg_base + IRB_ADDR0); in meson_irtx_setup()
107 ir->reg_base + IRB_ADDR3); in meson_irtx_setup()
108 writel(readl(ir->reg_base + IRB_ADDR0) | IRB_ENABLE, in meson_irtx_setup()
109 ir->reg_base + IRB_ADDR0); in meson_irtx_setup()
112 static u32 meson_irtx_prepare_pulse(struct meson_irtx *ir, unsigned int time) in meson_irtx_prepare_pulse() argument
116 unsigned int tb_us = DIV_ROUND_CLOSEST(USEC_PER_SEC, ir->carrier); in meson_irtx_prepare_pulse()
123 static u32 meson_irtx_prepare_space(struct meson_irtx *ir, unsigned int time) in meson_irtx_prepare_space() argument
145 static void meson_irtx_send_buffer(struct meson_irtx *ir) in meson_irtx_send_buffer() argument
150 while (ir->buf_head < ir->buf_len && nr < max_fifo_level) { in meson_irtx_send_buffer()
151 writel(ir->buf[ir->buf_head], ir->reg_base + IRB_ADDR2); in meson_irtx_send_buffer()
153 ir->buf_head++; in meson_irtx_send_buffer()
158 static bool meson_irtx_check_buf(struct meson_irtx *ir, in meson_irtx_check_buf() argument
170 max_tb_us = USEC_PER_SEC / ir->carrier; in meson_irtx_check_buf()
181 static void meson_irtx_fill_buf(struct meson_irtx *ir, u32 *dst_buf, in meson_irtx_fill_buf() argument
188 dst_buf[i] = meson_irtx_prepare_pulse(ir, src_buf[i]); in meson_irtx_fill_buf()
190 dst_buf[i] = meson_irtx_prepare_space(ir, src_buf[i]); in meson_irtx_fill_buf()
197 struct meson_irtx *ir = data; in meson_irtx_irqhandler() local
199 writel(readl(ir->reg_base + IRB_ADDR3) & ~IRB_FIFO_THD_PENDING, in meson_irtx_irqhandler()
200 ir->reg_base + IRB_ADDR3); in meson_irtx_irqhandler()
202 if (completion_done(&ir->completion)) in meson_irtx_irqhandler()
205 spin_lock_irqsave(&ir->lock, flags); in meson_irtx_irqhandler()
206 if (ir->buf_head < ir->buf_len) in meson_irtx_irqhandler()
207 meson_irtx_send_buffer(ir); in meson_irtx_irqhandler()
209 complete(&ir->completion); in meson_irtx_irqhandler()
210 spin_unlock_irqrestore(&ir->lock, flags); in meson_irtx_irqhandler()
217 struct meson_irtx *ir = rc->priv; in meson_irtx_set_carrier() local
222 ir->carrier = carrier; in meson_irtx_set_carrier()
223 meson_irtx_set_mod(ir); in meson_irtx_set_carrier()
230 struct meson_irtx *ir = rc->priv; in meson_irtx_set_duty_cycle() local
232 ir->duty_cycle = duty_cycle; in meson_irtx_set_duty_cycle()
233 meson_irtx_set_mod(ir); in meson_irtx_set_duty_cycle()
238 static void meson_irtx_update_buf(struct meson_irtx *ir, u32 *buf, in meson_irtx_update_buf() argument
241 ir->buf = buf; in meson_irtx_update_buf()
242 ir->buf_len = len; in meson_irtx_update_buf()
243 ir->buf_head = head; in meson_irtx_update_buf()
250 struct meson_irtx *ir = rc->priv; in meson_irtx_transmit() local
254 if (!meson_irtx_check_buf(ir, buf, len)) in meson_irtx_transmit()
261 meson_irtx_fill_buf(ir, tx_buf, buf, len); in meson_irtx_transmit()
262 dev_dbg(ir->dev, "TX buffer filled, length = %u\n", len); in meson_irtx_transmit()
264 spin_lock_irqsave(&ir->lock, flags); in meson_irtx_transmit()
265 meson_irtx_update_buf(ir, tx_buf, len, 0); in meson_irtx_transmit()
266 reinit_completion(&ir->completion); in meson_irtx_transmit()
267 meson_irtx_send_buffer(ir); in meson_irtx_transmit()
268 spin_unlock_irqrestore(&ir->lock, flags); in meson_irtx_transmit()
270 if (!wait_for_completion_timeout(&ir->completion, in meson_irtx_transmit()
274 spin_lock_irqsave(&ir->lock, flags); in meson_irtx_transmit()
275 kfree(ir->buf); in meson_irtx_transmit()
276 meson_irtx_update_buf(ir, NULL, 0, 0); in meson_irtx_transmit()
277 spin_unlock_irqrestore(&ir->lock, flags); in meson_irtx_transmit()
282 static int meson_irtx_mod_clock_probe(struct meson_irtx *ir, in meson_irtx_mod_clock_probe() argument
285 struct device_node *np = ir->dev->of_node; in meson_irtx_mod_clock_probe()
291 clock = devm_clk_get(ir->dev, "xtal"); in meson_irtx_mod_clock_probe()
296 ir->clk_rate = clk_get_rate(clock) / 3; in meson_irtx_mod_clock_probe()
298 if (ir->clk_rate < IRB_MOD_1US_CLK_RATE) { in meson_irtx_mod_clock_probe()
300 ir->clk_rate = IRB_MOD_1US_CLK_RATE; in meson_irtx_mod_clock_probe()
303 dev_info(ir->dev, "F_clk = %luHz\n", ir->clk_rate); in meson_irtx_mod_clock_probe()
311 struct meson_irtx *ir; in meson_irtx_probe() local
317 ir = devm_kzalloc(dev, sizeof(*ir), GFP_KERNEL); in meson_irtx_probe()
318 if (!ir) in meson_irtx_probe()
321 ir->reg_base = devm_platform_ioremap_resource(pdev, 0); in meson_irtx_probe()
322 if (IS_ERR(ir->reg_base)) in meson_irtx_probe()
323 return PTR_ERR(ir->reg_base); in meson_irtx_probe()
329 ir->dev = dev; in meson_irtx_probe()
330 ir->carrier = MIRTX_DEFAULT_CARRIER; in meson_irtx_probe()
331 ir->duty_cycle = MIRTX_DEFAULT_DUTY_CYCLE; in meson_irtx_probe()
332 init_completion(&ir->completion); in meson_irtx_probe()
333 spin_lock_init(&ir->lock); in meson_irtx_probe()
335 ret = meson_irtx_mod_clock_probe(ir, &clk_nr); in meson_irtx_probe()
339 meson_irtx_setup(ir, clk_nr); in meson_irtx_probe()
344 DRIVER_NAME, ir); in meson_irtx_probe()
354 rc->priv = ir; in meson_irtx_probe()
371 .compatible = "amlogic,meson-g12a-ir-tx",
386 MODULE_DESCRIPTION("Meson IR TX driver");