#include <linux/kdev_t.h>
#include <linux/display-sys.h>
-static struct list_head display_device_list;
+static struct list_head main_display_device_list;
+static struct list_head aux_display_device_list;
-static ssize_t display_show_name(struct device *dev,
- struct device_attribute *attr, char *buf)
+static ssize_t name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
+
return snprintf(buf, PAGE_SIZE, "%s\n", dsp->name);
}
-static ssize_t display_show_type(struct device *dev,
- struct device_attribute *attr, char *buf)
+static DEVICE_ATTR_RO(name);
+
+static ssize_t type_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
+
return snprintf(buf, PAGE_SIZE, "%s\n", dsp->type);
}
-static ssize_t display_show_enable(struct device *dev,
- struct device_attribute *attr, char *buf)
+static DEVICE_ATTR_RO(type);
+
+static ssize_t property_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", dsp->property);
+}
+
+static DEVICE_ATTR_RO(property);
+
+static ssize_t enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
int enable;
- if(dsp->ops && dsp->ops->getenable)
+
+ if (dsp->ops && dsp->ops->getenable)
enable = dsp->ops->getenable(dsp);
else
return 0;
return snprintf(buf, PAGE_SIZE, "%d\n", enable);
}
-static ssize_t display_store_enable(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t size)
+static ssize_t enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
int enable;
-
- sscanf(buf, "%d", &enable);
- if(dsp->ops && dsp->ops->setenable)
+
+ if (kstrtoint(buf, 0, &enable))
+ return size;
+ if (dsp->ops && dsp->ops->setenable)
dsp->ops->setenable(dsp, enable);
return size;
}
-static ssize_t display_show_connect(struct device *dev,
- struct device_attribute *attr, char *buf)
+static DEVICE_ATTR_RW(enable);
+
+static ssize_t connect_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
int connect;
- if(dsp->ops && dsp->ops->getstatus)
+
+ if (dsp->ops && dsp->ops->getstatus)
connect = dsp->ops->getstatus(dsp);
else
return 0;
return snprintf(buf, PAGE_SIZE, "%d\n", connect);
}
+static DEVICE_ATTR_RO(connect);
+
static int mode_string(char *buf, unsigned int offset,
const struct fb_videomode *mode)
{
-// char m = 'U';
char v = 'p';
-// if (mode->flag & FB_MODE_IS_DETAILED)
-// m = 'D';
-// if (mode->flag & FB_MODE_IS_VESA)
-// m = 'V';
-// if (mode->flag & FB_MODE_IS_STANDARD)
-// m = 'S';
-
+ if (!buf || !mode) {
+ pr_err("%s parameter error\n", __func__);
+ return 0;
+ }
+ if (mode->xres == 0 && mode->yres == 0)
+ return snprintf(&buf[offset], PAGE_SIZE - offset, "auto\n");
if (mode->vmode & FB_VMODE_INTERLACED)
v = 'i';
if (mode->vmode & FB_VMODE_DOUBLE)
v = 'd';
-
- return snprintf(&buf[offset], PAGE_SIZE - offset, "%dx%d%c-%d\n",
- mode->xres, mode->yres, v, mode->refresh);
+ if (mode->flag)
+ return snprintf(&buf[offset], PAGE_SIZE - offset,
+ "%dx%d%c-%d(YCbCr420)\n",
+ mode->xres, mode->yres, v, mode->refresh);
+ else
+ return snprintf(&buf[offset], PAGE_SIZE - offset,
+ "%dx%d%c-%d\n",
+ mode->xres, mode->yres, v, mode->refresh);
}
-static ssize_t display_show_modes(struct device *dev,
- struct device_attribute *attr, char *buf)
+
+static ssize_t modes_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
struct list_head *modelist, *pos;
- struct fb_modelist *fb_modelist;
+ struct display_modelist *display_modelist;
const struct fb_videomode *mode;
int i;
- if(dsp->ops && dsp->ops->getmodelist)
- {
- if(dsp->ops->getmodelist(dsp, &modelist))
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getmodelist) {
+ if (dsp->ops->getmodelist(dsp, &modelist)) {
+ mutex_unlock(&dsp->lock);
return -EINVAL;
- }
- else
+ }
+ } else {
+ mutex_unlock(&dsp->lock);
return 0;
-
+ }
i = 0;
+ if (dsp->priority == DISPLAY_PRIORITY_HDMI)
+ i += snprintf(buf, PAGE_SIZE, "auto\n");
+
list_for_each(pos, modelist) {
- fb_modelist = list_entry(pos, struct fb_modelist, list);
- mode = &fb_modelist->mode;
+ display_modelist = list_entry(pos,
+ struct display_modelist,
+ list);
+ mode = &display_modelist->mode;
i += mode_string(buf, i, mode);
}
+ mutex_unlock(&dsp->lock);
return i;
}
-static ssize_t display_show_mode(struct device *dev,
- struct device_attribute *attr, char *buf)
+static DEVICE_ATTR_RO(modes);
+
+static ssize_t mode_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
struct fb_videomode mode;
-
- if(dsp->ops && dsp->ops->getmode)
- if(dsp->ops->getmode(dsp, &mode) == 0)
+
+ if (dsp->ops && dsp->ops->getmode)
+ if (dsp->ops->getmode(dsp, &mode) == 0)
return mode_string(buf, 0, &mode);
return 0;
}
-static ssize_t display_store_mode(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t mode_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
char mstr[100];
struct list_head *modelist, *pos;
- struct fb_modelist *fb_modelist;
- struct fb_videomode *mode;
- size_t i;
-
- if(dsp->ops && dsp->ops->getmodelist)
- {
- if(dsp->ops && dsp->ops->getmodelist)
- {
- if(dsp->ops->getmodelist(dsp, &modelist))
+ struct display_modelist *display_modelist;
+ struct fb_videomode *mode;
+ size_t i;
+
+ mutex_lock(&dsp->lock);
+ if (!memcmp(buf, "auto", 4)) {
+ if (dsp->ops && dsp->ops->setmode)
+ dsp->ops->setmode(dsp, NULL);
+ mutex_unlock(&dsp->lock);
+ return count;
+ }
+
+ if (dsp->ops && dsp->ops->getmodelist) {
+ if (dsp->ops && dsp->ops->getmodelist) {
+ if (dsp->ops->getmodelist(dsp, &modelist)) {
+ mutex_unlock(&dsp->lock);
return -EINVAL;
+ }
}
list_for_each(pos, modelist) {
- fb_modelist = list_entry(pos, struct fb_modelist, list);
- mode = &fb_modelist->mode;
+ display_modelist = list_entry(pos,
+ struct display_modelist,
+ list);
+ mode = &display_modelist->mode;
i = mode_string(mstr, 0, mode);
if (strncmp(mstr, buf, max(count, i)) == 0) {
- if(dsp->ops && dsp->ops->setmode)
+ if (dsp->ops && dsp->ops->setmode)
dsp->ops->setmode(dsp, mode);
+ mutex_unlock(&dsp->lock);
return count;
}
}
}
+ mutex_unlock(&dsp->lock);
return -EINVAL;
}
-static ssize_t display_show_scale(struct device *dev,
- struct device_attribute *attr, char *buf)
+static DEVICE_ATTR_RW(mode);
+
+static ssize_t scale_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
int xscale, yscale;
-
- if(dsp->ops && dsp->ops->getscale) {
+
+ if (dsp->ops && dsp->ops->getscale) {
xscale = dsp->ops->getscale(dsp, DISPLAY_SCALE_X);
yscale = dsp->ops->getscale(dsp, DISPLAY_SCALE_Y);
- if(xscale && yscale)
- return snprintf(buf, PAGE_SIZE, "xscale=%d yscale=%d\n", xscale, yscale);
+ if (xscale && yscale)
+ return snprintf(buf, PAGE_SIZE,
+ "xscale=%d yscale=%d\n",
+ xscale, yscale);
}
return -EINVAL;
}
-static ssize_t display_store_scale(struct device *dev,
- struct device_attribute *attr,
- const char *buf, size_t count)
+static ssize_t scale_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
int scale = 100;
-
- if(dsp->ops && dsp->ops->setscale) {
- if(!strncmp(buf, "xscale", 6)) {
- sscanf(buf, "xscale=%d", &scale);
- dsp->ops->setscale(dsp, DISPLAY_SCALE_X, scale);
+
+ if (dsp->ops && dsp->ops->setscale) {
+ if (!strncmp(buf, "xscale", 6)) {
+ if (!kstrtoint(buf, 0, &scale))
+ dsp->ops->setscale(dsp,
+ DISPLAY_SCALE_X,
+ scale);
+ } else if (!strncmp(buf, "yscale", 6)) {
+ if (!kstrtoint(buf, 0, &scale))
+ dsp->ops->setscale(dsp,
+ DISPLAY_SCALE_Y,
+ scale);
+ } else {
+ if (!kstrtoint(buf, 0, &scale)) {
+ dsp->ops->setscale(dsp,
+ DISPLAY_SCALE_X,
+ scale);
+ dsp->ops->setscale(dsp,
+ DISPLAY_SCALE_Y,
+ scale);
+ }
}
- else if(!strncmp(buf, "yscale", 6)) {
- sscanf(buf, "yscale=%d", &scale);
- dsp->ops->setscale(dsp, DISPLAY_SCALE_Y, scale);
+ return count;
+ }
+ return -EINVAL;
+}
+
+static DEVICE_ATTR_RW(scale);
+
+static ssize_t mode3d_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ struct list_head *modelist, *pos;
+ struct display_modelist *display_modelist;
+ struct fb_videomode mode;
+ int i = 0, cur_3d_mode = -1;
+ char mode_str[128];
+ int mode_strlen, format_3d;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getmodelist) {
+ if (dsp->ops->getmodelist(dsp, &modelist)) {
+ mutex_unlock(&dsp->lock);
+ return -EINVAL;
}
- else {
- sscanf(buf, "%d", &scale);
- dsp->ops->setscale(dsp, DISPLAY_SCALE_X, scale);
- dsp->ops->setscale(dsp, DISPLAY_SCALE_Y, scale);
+ } else {
+ mutex_unlock(&dsp->lock);
+ return 0;
+ }
+
+ if (dsp->ops && dsp->ops->getmode) {
+ if (dsp->ops->getmode(dsp, &mode)) {
+ mutex_unlock(&dsp->lock);
+ return -EINVAL;
}
+ } else {
+ mutex_unlock(&dsp->lock);
+ return 0;
+ }
+
+ list_for_each(pos, modelist) {
+ display_modelist = list_entry(pos,
+ struct display_modelist,
+ list);
+ if (!fb_mode_is_equal(&mode, &display_modelist->mode))
+ display_modelist = NULL;
+ else
+ break;
+ }
+ if (display_modelist)
+ i = snprintf(buf, PAGE_SIZE, "3dmodes=%d\n",
+ display_modelist->format_3d);
+ else
+ i = snprintf(buf, PAGE_SIZE, "3dmodes=0\n");
+
+ if (dsp->ops && dsp->ops->get3dmode)
+ cur_3d_mode = dsp->ops->get3dmode(dsp);
+ i += snprintf(buf + i, PAGE_SIZE - i, "cur3dmode=%d\n", cur_3d_mode);
+
+ list_for_each(pos, modelist) {
+ display_modelist = list_entry(pos,
+ struct display_modelist,
+ list);
+ mode_strlen = mode_string(mode_str, 0,
+ &display_modelist->mode);
+ mode_str[mode_strlen - 1] = 0;
+ format_3d = display_modelist->format_3d;
+ i += snprintf(buf + i, PAGE_SIZE, "%s,%d\n",
+ mode_str, format_3d);
+ }
+ mutex_unlock(&dsp->lock);
+ return i;
+}
+
+static ssize_t mode3d_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int mode;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->set3dmode) {
+ if (!kstrtoint(buf, 0, &mode))
+ dsp->ops->set3dmode(dsp, mode);
+ mutex_unlock(&dsp->lock);
return count;
}
+ mutex_unlock(&dsp->lock);
return -EINVAL;
}
-static struct device_attribute display_attrs[] = {
- __ATTR(name, S_IRUGO, display_show_name, NULL),
- __ATTR(type, S_IRUGO, display_show_type, NULL),
- __ATTR(enable, 0664, display_show_enable, display_store_enable),
- __ATTR(connect, S_IRUGO, display_show_connect, NULL),
- __ATTR(modes, S_IRUGO, display_show_modes, NULL),
- __ATTR(mode, 0664, display_show_mode, display_store_mode),
- __ATTR(scale, 0664, display_show_scale, display_store_scale),
- __ATTR_NULL
+static DEVICE_ATTR_RW(mode3d);
+
+static ssize_t color_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int ret = 0;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getcolor)
+ ret = dsp->ops->getcolor(dsp, buf);
+ mutex_unlock(&dsp->lock);
+ return ret;
+}
+
+static ssize_t color_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->setcolor) {
+ if (!dsp->ops->setcolor(dsp, buf, count)) {
+ mutex_unlock(&dsp->lock);
+ return count;
+ }
+ }
+ mutex_unlock(&dsp->lock);
+ return -EINVAL;
+}
+
+static DEVICE_ATTR_RW(color);
+
+static ssize_t audioinfo_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ char audioinfo[200];
+ int ret = 0;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getedidaudioinfo) {
+ ret = dsp->ops->getedidaudioinfo(dsp, audioinfo, 200);
+ if (!ret) {
+ mutex_unlock(&dsp->lock);
+ return snprintf(buf, PAGE_SIZE, "%s\n", audioinfo);
+ }
+ }
+ mutex_unlock(&dsp->lock);
+ return -EINVAL;
+}
+
+static DEVICE_ATTR_RO(audioinfo);
+
+static ssize_t monspecs_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ struct fb_monspecs monspecs;
+ int ret = 0;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getmonspecs) {
+ ret = dsp->ops->getmonspecs(dsp, &monspecs);
+ if (!ret) {
+ mutex_unlock(&dsp->lock);
+ memcpy(buf, &monspecs, sizeof(struct fb_monspecs));
+ return sizeof(struct fb_monspecs);
+ }
+ }
+ mutex_unlock(&dsp->lock);
+ return -EINVAL;
+}
+
+static DEVICE_ATTR_RO(monspecs);
+
+static ssize_t debug_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int ret = -EINVAL;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getdebug)
+ ret = dsp->ops->getdebug(dsp, buf);
+ mutex_unlock(&dsp->lock);
+ return ret;
+}
+
+static ssize_t debug_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int cmd, ret = -EINVAL;
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->setdebug) {
+ if (kstrtoint(buf, 0, &cmd) == 0)
+ dsp->ops->setdebug(dsp, cmd);
+ ret = count;
+ }
+ mutex_unlock(&dsp->lock);
+ return ret;
+}
+
+static DEVICE_ATTR_RW(debug);
+
+static ssize_t prop_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct rk_display_device *dsp = dev_get_drvdata(dev);
+ int ret = -EINVAL;
+
+ mutex_lock(&dsp->lock);
+ if (dsp->ops && dsp->ops->getvrinfo)
+ ret = dsp->ops->getvrinfo(dsp, buf);
+ mutex_unlock(&dsp->lock);
+
+ return ret;
+}
+
+static DEVICE_ATTR_RO(prop);
+
+static struct attribute *display_device_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_type.attr,
+ &dev_attr_property.attr,
+ &dev_attr_enable.attr,
+ &dev_attr_connect.attr,
+ &dev_attr_modes.attr,
+ &dev_attr_mode.attr,
+ &dev_attr_scale.attr,
+ &dev_attr_mode3d.attr,
+ &dev_attr_color.attr,
+ &dev_attr_audioinfo.attr,
+ &dev_attr_monspecs.attr,
+ &dev_attr_debug.attr,
+ &dev_attr_prop.attr,
+ NULL,
};
+ATTRIBUTE_GROUPS(display_device);
+
static int display_suspend(struct device *dev, pm_message_t state)
{
struct rk_display_device *dsp = dev_get_drvdata(dev);
return 0;
};
+int display_add_videomode(const struct fb_videomode *mode,
+ struct list_head *head)
+{
+ struct list_head *pos;
+ struct display_modelist *modelist;
+ struct fb_videomode *m;
+ int found = 0;
+
+ list_for_each(pos, head) {
+ modelist = list_entry(pos, struct display_modelist, list);
+ m = &modelist->mode;
+ if (fb_mode_is_equal(m, mode)) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found) {
+ modelist = kmalloc(sizeof(*modelist),
+ GFP_KERNEL);
+
+ if (!modelist)
+ return -ENOMEM;
+ modelist->mode = *mode;
+ list_add(&modelist->list, head);
+ }
+ return 0;
+}
+
void rk_display_device_enable(struct rk_display_device *ddev)
{
-//#ifndef CONFIG_DISPLAY_AUTO_SWITCH
-// return;
-//#else
- struct list_head *pos, *head = &display_device_list;
- struct rk_display_device *dev = NULL, *dev_enabled = NULL, *dev_enable = NULL;
- int enable = 0,connect;
-
+ struct list_head *pos, *head;
+ struct rk_display_device *dev = NULL, *dev_enabled = NULL;
+ struct rk_display_device *dev_enable = NULL;
+ int enable = 0, connect;
+
+ if (ddev->property == DISPLAY_MAIN)
+ head = &main_display_device_list;
+ else
+ head = &aux_display_device_list;
+
list_for_each(pos, head) {
dev = list_entry(pos, struct rk_display_device, list);
enable = dev->ops->getenable(dev);
connect = dev->ops->getstatus(dev);
- if(connect)
+ if (connect)
dev_enable = dev;
- if(enable == 1)
+ if (enable == 1)
dev_enabled = dev;
}
- // If no device is connected, enable highest priority device.
- if(dev_enable == NULL) {
+ /* If no device is connected, enable highest priority device. */
+ if (!dev_enable) {
dev->ops->setenable(dev, 1);
return;
}
-
- if(dev_enable == dev_enabled) {
- if(dev_enable != ddev)
+
+ if (dev_enable == dev_enabled) {
+ if (dev_enable != ddev)
ddev->ops->setenable(ddev, 0);
- }
- else {
- if(dev_enabled)
+ } else {
+ if (dev_enabled &&
+ dev_enabled->priority != DISPLAY_PRIORITY_HDMI)
dev_enabled->ops->setenable(dev_enabled, 0);
dev_enable->ops->setenable(dev_enable, 1);
}
-
-
-//#endif
}
EXPORT_SYMBOL(rk_display_device_enable);
void rk_display_device_enable_other(struct rk_display_device *ddev)
{
-#ifndef CONFIG_DISPLAY_AUTO_SWITCH
+#ifndef CONFIG_DISPLAY_AUTO_SWITCH
return;
#else
- struct list_head *pos, *head = &display_device_list;
- struct rk_display_device *dev;
+ struct list_head *pos, *head;
+ struct rk_display_device *dev;
int connect = 0;
-
+
+ if (ddev->property == DISPLAY_MAIN)
+ head = &main_display_device_list;
+ else
+ head = &aux_display_device_list;
+
list_for_each_prev(pos, head) {
dev = list_entry(pos, struct rk_display_device, list);
- if(dev != ddev)
- {
+ if (dev != ddev) {
connect = dev->ops->getstatus(dev);
- if(connect)
- {
+ if (connect) {
dev->ops->setenable(dev, 1);
return;
}
#ifndef CONFIG_DISPLAY_AUTO_SWITCH
return;
#else
- struct list_head *pos, *head = &display_device_list;
- struct rk_display_device *dev;
+ struct list_head *pos, *head;
+ struct rk_display_device *dev;
int enable = 0;
-
+
+ if (ddev->property == DISPLAY_MAIN)
+ head = &main_display_device_list;
+ else
+ head = &aux_display_device_list;
+
list_for_each(pos, head) {
dev = list_entry(pos, struct rk_display_device, list);
- if(dev != ddev)
- {
+ if (dev != ddev) {
enable = dev->ops->getenable(dev);
- if(enable)
+ if (enable)
dev->ops->setenable(dev, 0);
}
}
}
EXPORT_SYMBOL(rk_display_device_disable_other);
-void rk_display_device_select(int priority)
+void rk_display_device_select(int property, int priority)
{
- struct list_head *pos, *head = &display_device_list;
+ struct list_head *pos, *head;
struct rk_display_device *dev;
int enable, found = 0;
-
+
+ if (property == DISPLAY_MAIN)
+ head = &main_display_device_list;
+ else
+ head = &aux_display_device_list;
+
list_for_each(pos, head) {
dev = list_entry(pos, struct rk_display_device, list);
- if(dev->priority == priority)
+ if (dev->priority == priority)
found = 1;
}
-
- if(!found)
- {
- printk("[%s] select display interface %d not exist\n", __FUNCTION__, priority);
+
+ if (!found) {
+ pr_err("[%s] select display interface %d not exist\n",
+ __func__, priority);
return;
}
-
+
list_for_each(pos, head) {
dev = list_entry(pos, struct rk_display_device, list);
enable = dev->ops->getenable(dev);
- if(dev->priority == priority)
- {
- if(!enable)
+ if (dev->priority == priority) {
+ if (!enable)
dev->ops->setenable(dev, 1);
- }
- else if(enable)
+ } else if (enable) {
dev->ops->setenable(dev, 0);
+ }
}
}
EXPORT_SYMBOL(rk_display_device_select);
static DEFINE_IDR(allocated_dsp);
static struct class *display_class;
-struct rk_display_device *rk_display_device_register(struct rk_display_driver *driver,
- struct device *parent, void *devdata)
+struct rk_display_device
+ *rk_display_device_register(struct rk_display_driver *driver,
+ struct device *parent, void *devdata)
{
struct rk_display_device *new_dev = NULL;
int ret = -EINVAL;
if (unlikely(!driver))
return ERR_PTR(ret);
- new_dev = kzalloc(sizeof(struct rk_display_device), GFP_KERNEL);
+ new_dev = kzalloc(sizeof(*new_dev), GFP_KERNEL);
if (likely(new_dev) && unlikely(driver->probe(new_dev, devdata))) {
- // Reserve the index for this display
+ /* Reserve the index for this display */
mutex_lock(&allocated_dsp_lock);
- new_dev->idx = idr_alloc(&allocated_dsp, new_dev, 0, 0, GFP_KERNEL);
+ new_dev->idx = idr_alloc(&allocated_dsp, new_dev,
+ 0, 0, GFP_KERNEL);
mutex_unlock(&allocated_dsp_lock);
if (new_dev->idx >= 0) {
- new_dev->dev = device_create(display_class, parent,
- MKDEV(0, 0), new_dev,
- "%s", new_dev->type);
+ struct list_head *pos, *head;
+ struct rk_display_device *dev;
+ int i = 0;
+
+ head = &main_display_device_list;
+ list_for_each_entry(dev, head, list) {
+ if (strcmp(dev->type, new_dev->type) == 0)
+ i++;
+ }
+ head = &aux_display_device_list;
+ list_for_each_entry(dev, head, list) {
+ if (strcmp(dev->type, new_dev->type) == 0)
+ i++;
+ }
+ if (i == 0)
+ new_dev->dev =
+ device_create(display_class, parent,
+ MKDEV(0, 0), new_dev,
+ "%s", new_dev->type);
+ else
+ new_dev->dev =
+ device_create(display_class, parent,
+ MKDEV(0, 0), new_dev,
+ "%s%d", new_dev->type, i);
+
if (!IS_ERR(new_dev->dev)) {
new_dev->parent = parent;
new_dev->driver = driver;
- if(parent)
+ if (parent)
new_dev->dev->driver = parent->driver;
mutex_init(&new_dev->lock);
- // Add new device to display device list.
- {
- struct list_head *pos, *head = &display_device_list;
- struct rk_display_device *dev;
-
- list_for_each(pos, head) {
- dev = list_entry(pos, struct rk_display_device, list);
- if(dev->priority > new_dev->priority)
- break;
- }
- list_add_tail(&new_dev->list, pos);
+ /* Add new device to display device list. */
+ if (new_dev->property == DISPLAY_MAIN)
+ head = &main_display_device_list;
+ else
+ head = &aux_display_device_list;
+
+ list_for_each(pos, head) {
+ dev =
+ list_entry(pos,
+ struct rk_display_device,
+ list);
+ if (dev->priority > new_dev->priority)
+ break;
}
+ list_add_tail(&new_dev->list, pos);
return new_dev;
}
mutex_lock(&allocated_dsp_lock);
{
if (!ddev)
return;
- // Free device
+ /* Free device */
mutex_lock(&ddev->lock);
device_unregister(ddev->dev);
mutex_unlock(&ddev->lock);
- // Mark device index as avaliable
+ /* Mark device index as available */
mutex_lock(&allocated_dsp_lock);
idr_remove(&allocated_dsp, ddev->idx);
mutex_unlock(&allocated_dsp_lock);
{
display_class = class_create(THIS_MODULE, "display");
if (IS_ERR(display_class)) {
- printk(KERN_ERR "Failed to create display class\n");
+ pr_err("Failed to create display class\n");
display_class = NULL;
return -EINVAL;
}
- display_class->dev_attrs = display_attrs;
+ display_class->dev_groups = display_device_groups;
display_class->suspend = display_suspend;
display_class->resume = display_resume;
mutex_init(&allocated_dsp_lock);
- INIT_LIST_HEAD(&display_device_list);
+ INIT_LIST_HEAD(&main_display_device_list);
+ INIT_LIST_HEAD(&aux_display_device_list);
return 0;
}
subsys_initcall(rk_display_class_init);
module_exit(rk_display_class_exit);
-
MODULE_AUTHOR("zhengyang@rock-chips.com");
MODULE_DESCRIPTION("Driver for rk display device");
MODULE_LICENSE("GPL");