media: cec-gpio: add notifier support
Add support for cec-notifier to the cec-gpio driver. This makes it possible to associate the CEC gpio pin with an HDMI connector. This feature was always documented in the cec-gpio bindings: Documentation/devicetree/bindings/media/cec-gpio.txt But support for the hdmi-phandle property was never actually implemented in this driver. This patch adds support for this property. It also fixes a few incorrect error returns in the probe() function, which skipped the call to cec_delete_adapter(). Tested on a Raspberry Pi 3B with a modified vc4 driver. Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
This commit is contained in:
parent
98f290731f
commit
7e86efa2ff
@ -588,6 +588,7 @@ config CEC_GPIO
|
||||
depends on PREEMPT || COMPILE_TEST
|
||||
select CEC_CORE
|
||||
select CEC_PIN
|
||||
select CEC_NOTIFIER
|
||||
select GPIOLIB
|
||||
help
|
||||
This is a generic GPIO-based CEC driver.
|
||||
|
@ -8,10 +8,12 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <media/cec-notifier.h>
|
||||
#include <media/cec-pin.h>
|
||||
|
||||
struct cec_gpio {
|
||||
struct cec_adapter *adap;
|
||||
struct cec_notifier *notifier;
|
||||
struct device *dev;
|
||||
|
||||
struct gpio_desc *cec_gpio;
|
||||
@ -173,9 +175,17 @@ static const struct cec_pin_ops cec_gpio_pin_ops = {
|
||||
static int cec_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device *hdmi_dev;
|
||||
struct cec_gpio *cec;
|
||||
u32 caps = CEC_CAP_DEFAULTS | CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN;
|
||||
int ret;
|
||||
|
||||
hdmi_dev = cec_notifier_parse_hdmi_phandle(dev);
|
||||
if (PTR_ERR(hdmi_dev) == -EPROBE_DEFER)
|
||||
return PTR_ERR(hdmi_dev);
|
||||
if (IS_ERR(hdmi_dev))
|
||||
caps |= CEC_CAP_PHYS_ADDR;
|
||||
|
||||
cec = devm_kzalloc(dev, sizeof(*cec), GFP_KERNEL);
|
||||
if (!cec)
|
||||
return -ENOMEM;
|
||||
@ -196,8 +206,7 @@ static int cec_gpio_probe(struct platform_device *pdev)
|
||||
return PTR_ERR(cec->v5_gpio);
|
||||
|
||||
cec->adap = cec_pin_allocate_adapter(&cec_gpio_pin_ops,
|
||||
cec, pdev->name, CEC_CAP_DEFAULTS | CEC_CAP_PHYS_ADDR |
|
||||
CEC_CAP_MONITOR_ALL | CEC_CAP_MONITOR_PIN);
|
||||
cec, pdev->name, caps);
|
||||
if (IS_ERR(cec->adap))
|
||||
return PTR_ERR(cec->adap);
|
||||
|
||||
@ -205,7 +214,7 @@ static int cec_gpio_probe(struct platform_device *pdev)
|
||||
IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
|
||||
cec->adap->name, cec);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto del_adap;
|
||||
|
||||
cec_gpio_disable_irq(cec->adap);
|
||||
|
||||
@ -218,7 +227,7 @@ static int cec_gpio_probe(struct platform_device *pdev)
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
|
||||
"hpd-gpio", cec);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto del_adap;
|
||||
}
|
||||
|
||||
if (cec->v5_gpio) {
|
||||
@ -230,23 +239,37 @@ static int cec_gpio_probe(struct platform_device *pdev)
|
||||
IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
|
||||
"v5-gpio", cec);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto del_adap;
|
||||
}
|
||||
|
||||
if (!IS_ERR(hdmi_dev)) {
|
||||
cec->notifier = cec_notifier_cec_adap_register(hdmi_dev, NULL,
|
||||
cec->adap);
|
||||
if (!cec->notifier) {
|
||||
ret = -ENOMEM;
|
||||
goto del_adap;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cec_register_adapter(cec->adap, &pdev->dev);
|
||||
if (ret) {
|
||||
cec_delete_adapter(cec->adap);
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
goto unreg_notifier;
|
||||
|
||||
platform_set_drvdata(pdev, cec);
|
||||
return 0;
|
||||
|
||||
unreg_notifier:
|
||||
cec_notifier_cec_adap_unregister(cec->notifier);
|
||||
del_adap:
|
||||
cec_delete_adapter(cec->adap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int cec_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cec_gpio *cec = platform_get_drvdata(pdev);
|
||||
|
||||
cec_notifier_cec_adap_unregister(cec->notifier);
|
||||
cec_unregister_adapter(cec->adap);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user