1 // SPDX-License-Identifier: GPL-2.0-only
3 * OPA362 analog video amplifier with output/power control
5 * Copyright (C) 2014 Golden Delicious Computers
6 * Author: H. Nikolaus Schaller <hns@goldelico.com>
8 * based on encoder-tfp410
10 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
11 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
14 #include <linux/gpio/consumer.h>
15 #include <linux/module.h>
16 #include <linux/platform_device.h>
17 #include <linux/slab.h>
19 #include "../dss/omapdss.h"
21 struct panel_drv_data
{
22 struct omap_dss_device dssdev
;
24 struct gpio_desc
*enable_gpio
;
27 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
29 static int opa362_connect(struct omap_dss_device
*src
,
30 struct omap_dss_device
*dst
)
32 return omapdss_device_connect(dst
->dss
, dst
, dst
->next
);
35 static void opa362_disconnect(struct omap_dss_device
*src
,
36 struct omap_dss_device
*dst
)
38 omapdss_device_disconnect(dst
, dst
->next
);
41 static void opa362_enable(struct omap_dss_device
*dssdev
)
43 struct panel_drv_data
*ddata
= to_panel_data(dssdev
);
45 if (ddata
->enable_gpio
)
46 gpiod_set_value_cansleep(ddata
->enable_gpio
, 1);
49 static void opa362_disable(struct omap_dss_device
*dssdev
)
51 struct panel_drv_data
*ddata
= to_panel_data(dssdev
);
53 if (ddata
->enable_gpio
)
54 gpiod_set_value_cansleep(ddata
->enable_gpio
, 0);
57 static const struct omap_dss_device_ops opa362_ops
= {
58 .connect
= opa362_connect
,
59 .disconnect
= opa362_disconnect
,
60 .enable
= opa362_enable
,
61 .disable
= opa362_disable
,
64 static int opa362_probe(struct platform_device
*pdev
)
66 struct panel_drv_data
*ddata
;
67 struct omap_dss_device
*dssdev
;
68 struct gpio_desc
*gpio
;
70 dev_dbg(&pdev
->dev
, "probe\n");
72 ddata
= devm_kzalloc(&pdev
->dev
, sizeof(*ddata
), GFP_KERNEL
);
76 platform_set_drvdata(pdev
, ddata
);
78 gpio
= devm_gpiod_get_optional(&pdev
->dev
, "enable", GPIOD_OUT_LOW
);
82 ddata
->enable_gpio
= gpio
;
84 dssdev
= &ddata
->dssdev
;
85 dssdev
->ops
= &opa362_ops
;
86 dssdev
->dev
= &pdev
->dev
;
87 dssdev
->type
= OMAP_DISPLAY_TYPE_VENC
;
88 dssdev
->owner
= THIS_MODULE
;
89 dssdev
->of_ports
= BIT(1) | BIT(0);
91 dssdev
->next
= omapdss_of_find_connected_device(pdev
->dev
.of_node
, 1);
92 if (IS_ERR(dssdev
->next
)) {
93 if (PTR_ERR(dssdev
->next
) != -EPROBE_DEFER
)
94 dev_err(&pdev
->dev
, "failed to find video sink\n");
95 return PTR_ERR(dssdev
->next
);
98 omapdss_device_register(dssdev
);
103 static int __exit
opa362_remove(struct platform_device
*pdev
)
105 struct panel_drv_data
*ddata
= platform_get_drvdata(pdev
);
106 struct omap_dss_device
*dssdev
= &ddata
->dssdev
;
109 omapdss_device_put(dssdev
->next
);
110 omapdss_device_unregister(&ddata
->dssdev
);
112 opa362_disable(dssdev
);
117 static const struct of_device_id opa362_of_match
[] = {
118 { .compatible
= "omapdss,ti,opa362", },
121 MODULE_DEVICE_TABLE(of
, opa362_of_match
);
123 static struct platform_driver opa362_driver
= {
124 .probe
= opa362_probe
,
125 .remove
= __exit_p(opa362_remove
),
127 .name
= "amplifier-opa362",
128 .of_match_table
= opa362_of_match
,
129 .suppress_bind_attrs
= true,
133 module_platform_driver(opa362_driver
);
135 MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
136 MODULE_DESCRIPTION("OPA362 analog video amplifier with output/power control");
137 MODULE_LICENSE("GPL v2");