2 * OPA362 analog video amplifier with output/power control
4 * Copyright (C) 2014 Golden Delicious Computers
5 * Author: H. Nikolaus Schaller <hns@goldelico.com>
7 * based on encoder-tfp410
9 * Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
10 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License version 2 as published by
14 * the Free Software Foundation.
17 #include <linux/gpio/consumer.h>
18 #include <linux/module.h>
19 #include <linux/platform_device.h>
20 #include <linux/slab.h>
22 #include "../dss/omapdss.h"
24 struct panel_drv_data
{
25 struct omap_dss_device dssdev
;
27 struct gpio_desc
*enable_gpio
;
30 #define to_panel_data(x) container_of(x, struct panel_drv_data, dssdev)
32 static int opa362_connect(struct omap_dss_device
*src
,
33 struct omap_dss_device
*dst
)
35 return omapdss_device_connect(dst
->dss
, dst
, dst
->next
);
38 static void opa362_disconnect(struct omap_dss_device
*src
,
39 struct omap_dss_device
*dst
)
41 omapdss_device_disconnect(dst
, dst
->next
);
44 static int opa362_enable(struct omap_dss_device
*dssdev
)
46 struct panel_drv_data
*ddata
= to_panel_data(dssdev
);
47 struct omap_dss_device
*src
= dssdev
->src
;
50 dev_dbg(dssdev
->dev
, "enable\n");
52 if (!omapdss_device_is_connected(dssdev
))
55 if (omapdss_device_is_enabled(dssdev
))
58 r
= src
->ops
->enable(src
);
62 if (ddata
->enable_gpio
)
63 gpiod_set_value_cansleep(ddata
->enable_gpio
, 1);
65 dssdev
->state
= OMAP_DSS_DISPLAY_ACTIVE
;
70 static void opa362_disable(struct omap_dss_device
*dssdev
)
72 struct panel_drv_data
*ddata
= to_panel_data(dssdev
);
73 struct omap_dss_device
*src
= dssdev
->src
;
75 dev_dbg(dssdev
->dev
, "disable\n");
77 if (!omapdss_device_is_enabled(dssdev
))
80 if (ddata
->enable_gpio
)
81 gpiod_set_value_cansleep(ddata
->enable_gpio
, 0);
83 src
->ops
->disable(src
);
85 dssdev
->state
= OMAP_DSS_DISPLAY_DISABLED
;
88 static const struct omap_dss_device_ops opa362_ops
= {
89 .connect
= opa362_connect
,
90 .disconnect
= opa362_disconnect
,
91 .enable
= opa362_enable
,
92 .disable
= opa362_disable
,
95 static int opa362_probe(struct platform_device
*pdev
)
97 struct panel_drv_data
*ddata
;
98 struct omap_dss_device
*dssdev
;
99 struct gpio_desc
*gpio
;
101 dev_dbg(&pdev
->dev
, "probe\n");
103 ddata
= devm_kzalloc(&pdev
->dev
, sizeof(*ddata
), GFP_KERNEL
);
107 platform_set_drvdata(pdev
, ddata
);
109 gpio
= devm_gpiod_get_optional(&pdev
->dev
, "enable", GPIOD_OUT_LOW
);
111 return PTR_ERR(gpio
);
113 ddata
->enable_gpio
= gpio
;
115 dssdev
= &ddata
->dssdev
;
116 dssdev
->ops
= &opa362_ops
;
117 dssdev
->dev
= &pdev
->dev
;
118 dssdev
->type
= OMAP_DISPLAY_TYPE_VENC
;
119 dssdev
->output_type
= OMAP_DISPLAY_TYPE_VENC
;
120 dssdev
->owner
= THIS_MODULE
;
121 dssdev
->of_ports
= BIT(1) | BIT(0);
123 dssdev
->next
= omapdss_of_find_connected_device(pdev
->dev
.of_node
, 1);
124 if (IS_ERR(dssdev
->next
)) {
125 if (PTR_ERR(dssdev
->next
) != -EPROBE_DEFER
)
126 dev_err(&pdev
->dev
, "failed to find video sink\n");
127 return PTR_ERR(dssdev
->next
);
130 omapdss_device_register(dssdev
);
135 static int __exit
opa362_remove(struct platform_device
*pdev
)
137 struct panel_drv_data
*ddata
= platform_get_drvdata(pdev
);
138 struct omap_dss_device
*dssdev
= &ddata
->dssdev
;
141 omapdss_device_put(dssdev
->next
);
142 omapdss_device_unregister(&ddata
->dssdev
);
144 WARN_ON(omapdss_device_is_enabled(dssdev
));
145 if (omapdss_device_is_enabled(dssdev
))
146 opa362_disable(dssdev
);
148 WARN_ON(omapdss_device_is_connected(dssdev
));
149 if (omapdss_device_is_connected(dssdev
))
150 omapdss_device_disconnect(NULL
, dssdev
);
155 static const struct of_device_id opa362_of_match
[] = {
156 { .compatible
= "omapdss,ti,opa362", },
159 MODULE_DEVICE_TABLE(of
, opa362_of_match
);
161 static struct platform_driver opa362_driver
= {
162 .probe
= opa362_probe
,
163 .remove
= __exit_p(opa362_remove
),
165 .name
= "amplifier-opa362",
166 .of_match_table
= opa362_of_match
,
167 .suppress_bind_attrs
= true,
171 module_platform_driver(opa362_driver
);
173 MODULE_AUTHOR("H. Nikolaus Schaller <hns@goldelico.com>");
174 MODULE_DESCRIPTION("OPA362 analog video amplifier with output/power control");
175 MODULE_LICENSE("GPL v2");