Lines Matching +full:cec +full:- +full:irq
1 // SPDX-License-Identifier: GPL-2.0-only
20 #include <media/cec.h>
21 #include <media/cec-notifier.h>
79 if (WARN_ON(cnt > sizeof(buf) - 1)) in tda9950_write_range()
80 return -EINVAL; in tda9950_write_range()
85 msg.addr = client->addr; in tda9950_write_range()
90 dev_dbg(&client->dev, "wr 0x%02x: %*ph\n", addr, cnt, p); in tda9950_write_range()
92 ret = i2c_transfer(client->adapter, &msg, 1); in tda9950_write_range()
94 dev_err(&client->dev, "Error %d writing to cec:0x%x\n", ret, addr); in tda9950_write_range()
108 msg[0].addr = client->addr; in tda9950_read_range()
112 msg[1].addr = client->addr; in tda9950_read_range()
117 ret = i2c_transfer(client->adapter, msg, 2); in tda9950_read_range()
119 dev_err(&client->dev, "Error %d reading from cec:0x%x\n", ret, addr); in tda9950_read_range()
121 dev_dbg(&client->dev, "rd 0x%02x: %*ph\n", addr, cnt, p); in tda9950_read_range()
138 static irqreturn_t tda9950_irq(int irq, void *data) in tda9950_irq() argument
145 if (!priv->open) in tda9950_irq()
148 csr = tda9950_read(priv->client, REG_CSR); in tda9950_irq()
152 cconr = tda9950_read(priv->client, REG_CCONR) & CCONR_RETRY_MASK; in tda9950_irq()
154 tda9950_read_range(priv->client, REG_CDR0, buf, sizeof(buf)); in tda9950_irq()
161 dev_warn(&priv->client->dev, "interrupt pending, but no message?\n"); in tda9950_irq()
184 dev_err(&priv->client->dev, "CNF reply error 0x%02x\n", in tda9950_irq()
193 cec_transmit_done(priv->adap, tx_status, arb_lost_cnt, in tda9950_irq()
198 priv->rx_msg.len = buf[0] - 2; in tda9950_irq()
199 if (priv->rx_msg.len > CEC_MAX_MSG_SIZE) in tda9950_irq()
200 priv->rx_msg.len = CEC_MAX_MSG_SIZE; in tda9950_irq()
202 memcpy(priv->rx_msg.msg, buf + 2, priv->rx_msg.len); in tda9950_irq()
203 cec_received_msg(priv->adap, &priv->rx_msg); in tda9950_irq()
207 dev_err(&priv->client->dev, "unknown service id 0x%02x\n", in tda9950_irq()
218 struct tda9950_priv *priv = adap->priv; in tda9950_cec_transmit()
221 buf[0] = 2 + msg->len; in tda9950_cec_transmit()
223 memcpy(buf + 2, msg->msg, msg->len); in tda9950_cec_transmit()
228 tda9950_write(priv->client, REG_CCONR, attempts); in tda9950_cec_transmit()
230 return tda9950_write_range(priv->client, REG_CDR0, buf, 2 + msg->len); in tda9950_cec_transmit()
235 struct tda9950_priv *priv = adap->priv; in tda9950_cec_adap_log_addr()
240 addresses = priv->addresses = 0; in tda9950_cec_adap_log_addr()
242 addresses = priv->addresses |= BIT(addr); in tda9950_cec_adap_log_addr()
249 return tda9950_write_range(priv->client, REG_ACKH, buf, 2); in tda9950_cec_adap_log_addr()
262 if (priv->glue && priv->glue->open) in tda9950_glue_open()
263 ret = priv->glue->open(priv->glue->data); in tda9950_glue_open()
265 priv->open = true; in tda9950_glue_open()
272 priv->open = false; in tda9950_glue_release()
274 if (priv->glue && priv->glue->release) in tda9950_glue_release()
275 priv->glue->release(priv->glue->data); in tda9950_glue_release()
280 struct i2c_client *client = priv->client; in tda9950_open()
291 tda9950_cec_adap_log_addr(priv->adap, CEC_LOG_ADDR_INVALID); in tda9950_open()
301 struct i2c_client *client = priv->client; in tda9950_release()
308 /* Wait up to .5s for it to signal non-busy */ in tda9950_release()
311 if (!(csr & CSR_BUSY) || !--timeout) in tda9950_release()
316 /* Warn the user that their IRQ may die if it's shared. */ in tda9950_release()
318 dev_warn(&client->dev, "command processor failed to stop, irq%d may die (csr=0x%02x)\n", in tda9950_release()
319 client->irq, csr); in tda9950_release()
326 struct tda9950_priv *priv = adap->priv; in tda9950_cec_adap_enable()
350 if (glue && glue->exit) in tda9950_devm_glue_exit()
351 glue->exit(glue->data); in tda9950_devm_glue_exit()
358 if (glue && glue->init) { in tda9950_devm_glue_init()
359 ret = glue->init(glue->data); in tda9950_devm_glue_init()
375 cec_delete_adapter(priv->adap); in tda9950_cec_del()
380 struct tda9950_glue *glue = client->dev.platform_data; in tda9950_probe()
381 struct device *dev = &client->dev; in tda9950_probe()
388 * We must have I2C functionality: our multi-byte accesses in tda9950_probe()
391 if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { in tda9950_probe()
392 dev_err(&client->dev, in tda9950_probe()
394 return -ENXIO; in tda9950_probe()
398 if (client->irq <= 0) { in tda9950_probe()
399 dev_err(&client->dev, "driver requires an interrupt\n"); in tda9950_probe()
400 return -ENXIO; in tda9950_probe()
405 return -ENOMEM; in tda9950_probe()
407 priv->client = client; in tda9950_probe()
408 priv->glue = glue; in tda9950_probe()
415 * between the HDMI interface and the CEC interface. in tda9950_probe()
417 priv->hdmi = dev; in tda9950_probe()
418 if (glue && glue->parent) in tda9950_probe()
419 priv->hdmi = glue->parent; in tda9950_probe()
421 priv->adap = cec_allocate_adapter(&tda9950_cec_ops, priv, "tda9950", in tda9950_probe()
425 if (IS_ERR(priv->adap)) in tda9950_probe()
426 return PTR_ERR(priv->adap); in tda9950_probe()
430 cec_delete_adapter(priv->adap); in tda9950_probe()
444 dev_info(&client->dev, in tda9950_probe()
445 "TDA9950 CEC interface, hardware version %u.%u\n", in tda9950_probe()
452 irqflags = glue->irq_flags; in tda9950_probe()
454 ret = devm_request_threaded_irq(dev, client->irq, NULL, tda9950_irq, in tda9950_probe()
456 dev_name(&client->dev), priv); in tda9950_probe()
460 priv->notify = cec_notifier_cec_adap_register(priv->hdmi, NULL, in tda9950_probe()
461 priv->adap); in tda9950_probe()
462 if (!priv->notify) in tda9950_probe()
463 return -ENOMEM; in tda9950_probe()
465 ret = cec_register_adapter(priv->adap, priv->hdmi); in tda9950_probe()
467 cec_notifier_cec_adap_unregister(priv->notify, priv->adap); in tda9950_probe()
472 * CEC documentation says we must not call cec_delete_adapter in tda9950_probe()
484 cec_notifier_cec_adap_unregister(priv->notify, priv->adap); in tda9950_remove()
485 cec_unregister_adapter(priv->adap); in tda9950_remove()