mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-12-25 05:38:29 +07:00
ecc8b37089
We are about to remove the dss bus support, which also means that the omap_dss_device won't be a real device anymore. This means that the embedded "dev" struct needs to be removed from omap_dss_device. After we've finished the removal of the dss bus, we see the following changes: - struct omap_dss_device won't be a real Linux device anymore, but more like a "display entity". - struct omap_dss_driver won't be a Linux device driver, but "display entity ops". - The panel devices/drivers won't be omapdss devices/drivers, but platform/i2c/spi/etc devices/drivers, whichever fits the control mechanism of the panel. - The panel drivers will create omap_dss_device and omap_dss_driver, fill the required fields, and register the omap_dss_device to omapdss. - omap_dss_device won't have an embedded dev struct anymore, but a dev pointer to the actual device that manages the omap_dss_device. The model described above resembles the model that has been discussed with CDF (common display framework). For the duration of the conversion, we temporarily have two devs in the dssdev, the old "old_dev", which is a full embedded device struct, and the new "dev", which is a pointer to the device. "old_dev" will be removed in the future. For devices belonging to dss bus the dev is initialized to point to old_dev. This way all the code can just use the dev, for both old and new style panels. Both the new and old style panel drivers work during the conversion, and only after the dss bus support is removed will the old style panels stop to compile. Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
233 lines
5.2 KiB
C
233 lines
5.2 KiB
C
/*
|
|
* Copyright (C) 2009 Nokia Corporation
|
|
* Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
|
|
*
|
|
* VENC panel driver
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 as published by
|
|
* the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/err.h>
|
|
#include <linux/io.h>
|
|
#include <linux/mutex.h>
|
|
#include <linux/module.h>
|
|
|
|
#include <video/omapdss.h>
|
|
|
|
#include "dss.h"
|
|
|
|
static struct {
|
|
struct mutex lock;
|
|
} venc_panel;
|
|
|
|
static ssize_t display_output_type_show(struct device *dev,
|
|
struct device_attribute *attr, char *buf)
|
|
{
|
|
struct omap_dss_device *dssdev = to_dss_device(dev);
|
|
const char *ret;
|
|
|
|
switch (dssdev->phy.venc.type) {
|
|
case OMAP_DSS_VENC_TYPE_COMPOSITE:
|
|
ret = "composite";
|
|
break;
|
|
case OMAP_DSS_VENC_TYPE_SVIDEO:
|
|
ret = "svideo";
|
|
break;
|
|
default:
|
|
return -EINVAL;
|
|
}
|
|
|
|
return snprintf(buf, PAGE_SIZE, "%s\n", ret);
|
|
}
|
|
|
|
static ssize_t display_output_type_store(struct device *dev,
|
|
struct device_attribute *attr, const char *buf, size_t size)
|
|
{
|
|
struct omap_dss_device *dssdev = to_dss_device(dev);
|
|
enum omap_dss_venc_type new_type;
|
|
|
|
if (sysfs_streq("composite", buf))
|
|
new_type = OMAP_DSS_VENC_TYPE_COMPOSITE;
|
|
else if (sysfs_streq("svideo", buf))
|
|
new_type = OMAP_DSS_VENC_TYPE_SVIDEO;
|
|
else
|
|
return -EINVAL;
|
|
|
|
mutex_lock(&venc_panel.lock);
|
|
|
|
if (dssdev->phy.venc.type != new_type) {
|
|
dssdev->phy.venc.type = new_type;
|
|
omapdss_venc_set_type(dssdev, new_type);
|
|
if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
|
|
omapdss_venc_display_disable(dssdev);
|
|
omapdss_venc_display_enable(dssdev);
|
|
}
|
|
}
|
|
|
|
mutex_unlock(&venc_panel.lock);
|
|
|
|
return size;
|
|
}
|
|
|
|
static DEVICE_ATTR(output_type, S_IRUGO | S_IWUSR,
|
|
display_output_type_show, display_output_type_store);
|
|
|
|
static int venc_panel_probe(struct omap_dss_device *dssdev)
|
|
{
|
|
/* set default timings to PAL */
|
|
const struct omap_video_timings default_timings = {
|
|
.x_res = 720,
|
|
.y_res = 574,
|
|
.pixel_clock = 13500,
|
|
.hsw = 64,
|
|
.hfp = 12,
|
|
.hbp = 68,
|
|
.vsw = 5,
|
|
.vfp = 5,
|
|
.vbp = 41,
|
|
|
|
.vsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
|
|
.hsync_level = OMAPDSS_SIG_ACTIVE_HIGH,
|
|
|
|
.interlace = true,
|
|
};
|
|
|
|
mutex_init(&venc_panel.lock);
|
|
|
|
dssdev->panel.timings = default_timings;
|
|
|
|
return device_create_file(dssdev->dev, &dev_attr_output_type);
|
|
}
|
|
|
|
static void venc_panel_remove(struct omap_dss_device *dssdev)
|
|
{
|
|
device_remove_file(dssdev->dev, &dev_attr_output_type);
|
|
}
|
|
|
|
static int venc_panel_enable(struct omap_dss_device *dssdev)
|
|
{
|
|
int r;
|
|
|
|
dev_dbg(dssdev->dev, "venc_panel_enable\n");
|
|
|
|
mutex_lock(&venc_panel.lock);
|
|
|
|
if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
|
|
r = -EINVAL;
|
|
goto err;
|
|
}
|
|
|
|
omapdss_venc_set_timings(dssdev, &dssdev->panel.timings);
|
|
omapdss_venc_set_type(dssdev, dssdev->phy.venc.type);
|
|
omapdss_venc_invert_vid_out_polarity(dssdev,
|
|
dssdev->phy.venc.invert_polarity);
|
|
|
|
r = omapdss_venc_display_enable(dssdev);
|
|
if (r)
|
|
goto err;
|
|
|
|
dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
|
|
|
|
mutex_unlock(&venc_panel.lock);
|
|
|
|
return 0;
|
|
err:
|
|
mutex_unlock(&venc_panel.lock);
|
|
|
|
return r;
|
|
}
|
|
|
|
static void venc_panel_disable(struct omap_dss_device *dssdev)
|
|
{
|
|
dev_dbg(dssdev->dev, "venc_panel_disable\n");
|
|
|
|
mutex_lock(&venc_panel.lock);
|
|
|
|
if (dssdev->state == OMAP_DSS_DISPLAY_DISABLED)
|
|
goto end;
|
|
|
|
omapdss_venc_display_disable(dssdev);
|
|
|
|
dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
|
|
end:
|
|
mutex_unlock(&venc_panel.lock);
|
|
}
|
|
|
|
static void venc_panel_set_timings(struct omap_dss_device *dssdev,
|
|
struct omap_video_timings *timings)
|
|
{
|
|
dev_dbg(dssdev->dev, "venc_panel_set_timings\n");
|
|
|
|
mutex_lock(&venc_panel.lock);
|
|
|
|
omapdss_venc_set_timings(dssdev, timings);
|
|
dssdev->panel.timings = *timings;
|
|
|
|
mutex_unlock(&venc_panel.lock);
|
|
}
|
|
|
|
static int venc_panel_check_timings(struct omap_dss_device *dssdev,
|
|
struct omap_video_timings *timings)
|
|
{
|
|
dev_dbg(dssdev->dev, "venc_panel_check_timings\n");
|
|
|
|
return omapdss_venc_check_timings(dssdev, timings);
|
|
}
|
|
|
|
static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
|
|
{
|
|
dev_dbg(dssdev->dev, "venc_panel_get_wss\n");
|
|
|
|
return omapdss_venc_get_wss(dssdev);
|
|
}
|
|
|
|
static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
|
|
{
|
|
dev_dbg(dssdev->dev, "venc_panel_set_wss\n");
|
|
|
|
return omapdss_venc_set_wss(dssdev, wss);
|
|
}
|
|
|
|
static struct omap_dss_driver venc_driver = {
|
|
.probe = venc_panel_probe,
|
|
.remove = venc_panel_remove,
|
|
|
|
.enable = venc_panel_enable,
|
|
.disable = venc_panel_disable,
|
|
|
|
.get_resolution = omapdss_default_get_resolution,
|
|
.get_recommended_bpp = omapdss_default_get_recommended_bpp,
|
|
|
|
.set_timings = venc_panel_set_timings,
|
|
.check_timings = venc_panel_check_timings,
|
|
|
|
.get_wss = venc_panel_get_wss,
|
|
.set_wss = venc_panel_set_wss,
|
|
|
|
.driver = {
|
|
.name = "venc",
|
|
.owner = THIS_MODULE,
|
|
},
|
|
};
|
|
|
|
int venc_panel_init(void)
|
|
{
|
|
return omap_dss_register_driver(&venc_driver);
|
|
}
|
|
|
|
void venc_panel_exit(void)
|
|
{
|
|
omap_dss_unregister_driver(&venc_driver);
|
|
}
|