Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (C) 2012 Texas Instruments Ltd
0004  * Author: Archit Taneja <archit@ti.com>
0005  */
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/module.h>
0009 #include <linux/platform_device.h>
0010 #include <linux/slab.h>
0011 #include <linux/of.h>
0012 
0013 #include <video/omapfb_dss.h>
0014 
0015 #include "dss.h"
0016 
0017 static LIST_HEAD(output_list);
0018 static DEFINE_MUTEX(output_lock);
0019 
0020 int omapdss_output_set_device(struct omap_dss_device *out,
0021         struct omap_dss_device *dssdev)
0022 {
0023     int r;
0024 
0025     mutex_lock(&output_lock);
0026 
0027     if (out->dst) {
0028         DSSERR("output already has device %s connected to it\n",
0029             out->dst->name);
0030         r = -EINVAL;
0031         goto err;
0032     }
0033 
0034     if (out->output_type != dssdev->type) {
0035         DSSERR("output type and display type don't match\n");
0036         r = -EINVAL;
0037         goto err;
0038     }
0039 
0040     out->dst = dssdev;
0041     dssdev->src = out;
0042 
0043     mutex_unlock(&output_lock);
0044 
0045     return 0;
0046 err:
0047     mutex_unlock(&output_lock);
0048 
0049     return r;
0050 }
0051 EXPORT_SYMBOL(omapdss_output_set_device);
0052 
0053 int omapdss_output_unset_device(struct omap_dss_device *out)
0054 {
0055     int r;
0056 
0057     mutex_lock(&output_lock);
0058 
0059     if (!out->dst) {
0060         DSSERR("output doesn't have a device connected to it\n");
0061         r = -EINVAL;
0062         goto err;
0063     }
0064 
0065     if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) {
0066         DSSERR("device %s is not disabled, cannot unset device\n",
0067                 out->dst->name);
0068         r = -EINVAL;
0069         goto err;
0070     }
0071 
0072     out->dst->src = NULL;
0073     out->dst = NULL;
0074 
0075     mutex_unlock(&output_lock);
0076 
0077     return 0;
0078 err:
0079     mutex_unlock(&output_lock);
0080 
0081     return r;
0082 }
0083 EXPORT_SYMBOL(omapdss_output_unset_device);
0084 
0085 int omapdss_register_output(struct omap_dss_device *out)
0086 {
0087     list_add_tail(&out->list, &output_list);
0088     return 0;
0089 }
0090 EXPORT_SYMBOL(omapdss_register_output);
0091 
0092 void omapdss_unregister_output(struct omap_dss_device *out)
0093 {
0094     list_del(&out->list);
0095 }
0096 EXPORT_SYMBOL(omapdss_unregister_output);
0097 
0098 struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
0099 {
0100     struct omap_dss_device *out;
0101 
0102     list_for_each_entry(out, &output_list, list) {
0103         if (out->id == id)
0104             return out;
0105     }
0106 
0107     return NULL;
0108 }
0109 EXPORT_SYMBOL(omap_dss_get_output);
0110 
0111 struct omap_dss_device *omap_dss_find_output(const char *name)
0112 {
0113     struct omap_dss_device *out;
0114 
0115     list_for_each_entry(out, &output_list, list) {
0116         if (strcmp(out->name, name) == 0)
0117             return omap_dss_get_device(out);
0118     }
0119 
0120     return NULL;
0121 }
0122 EXPORT_SYMBOL(omap_dss_find_output);
0123 
0124 struct omap_dss_device *omap_dss_find_output_by_port_node(struct device_node *port)
0125 {
0126     struct device_node *src_node;
0127     struct omap_dss_device *out;
0128     u32 reg;
0129 
0130     src_node = dss_of_port_get_parent_device(port);
0131     if (!src_node)
0132         return NULL;
0133 
0134     reg = dss_of_port_get_port_number(port);
0135 
0136     list_for_each_entry(out, &output_list, list) {
0137         if (out->dev->of_node == src_node && out->port_num == reg) {
0138             of_node_put(src_node);
0139             return omap_dss_get_device(out);
0140         }
0141     }
0142 
0143     of_node_put(src_node);
0144 
0145     return NULL;
0146 }
0147 EXPORT_SYMBOL(omap_dss_find_output_by_port_node);
0148 
0149 struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
0150 {
0151     while (dssdev->src)
0152         dssdev = dssdev->src;
0153 
0154     if (dssdev->id != 0)
0155         return omap_dss_get_device(dssdev);
0156 
0157     return NULL;
0158 }
0159 EXPORT_SYMBOL(omapdss_find_output_from_display);
0160 
0161 struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev)
0162 {
0163     struct omap_dss_device *out;
0164     struct omap_overlay_manager *mgr;
0165 
0166     out = omapdss_find_output_from_display(dssdev);
0167 
0168     if (out == NULL)
0169         return NULL;
0170 
0171     mgr = out->manager;
0172 
0173     omap_dss_put_device(out);
0174 
0175     return mgr;
0176 }
0177 EXPORT_SYMBOL(omapdss_find_mgr_from_display);
0178 
0179 static const struct dss_mgr_ops *dss_mgr_ops;
0180 
0181 int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
0182 {
0183     if (dss_mgr_ops)
0184         return -EBUSY;
0185 
0186     dss_mgr_ops = mgr_ops;
0187 
0188     return 0;
0189 }
0190 EXPORT_SYMBOL(dss_install_mgr_ops);
0191 
0192 void dss_uninstall_mgr_ops(void)
0193 {
0194     dss_mgr_ops = NULL;
0195 }
0196 EXPORT_SYMBOL(dss_uninstall_mgr_ops);
0197 
0198 int dss_mgr_connect(struct omap_overlay_manager *mgr,
0199         struct omap_dss_device *dst)
0200 {
0201     return dss_mgr_ops->connect(mgr, dst);
0202 }
0203 EXPORT_SYMBOL(dss_mgr_connect);
0204 
0205 void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
0206         struct omap_dss_device *dst)
0207 {
0208     dss_mgr_ops->disconnect(mgr, dst);
0209 }
0210 EXPORT_SYMBOL(dss_mgr_disconnect);
0211 
0212 void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
0213         const struct omap_video_timings *timings)
0214 {
0215     dss_mgr_ops->set_timings(mgr, timings);
0216 }
0217 EXPORT_SYMBOL(dss_mgr_set_timings);
0218 
0219 void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
0220         const struct dss_lcd_mgr_config *config)
0221 {
0222     dss_mgr_ops->set_lcd_config(mgr, config);
0223 }
0224 EXPORT_SYMBOL(dss_mgr_set_lcd_config);
0225 
0226 int dss_mgr_enable(struct omap_overlay_manager *mgr)
0227 {
0228     return dss_mgr_ops->enable(mgr);
0229 }
0230 EXPORT_SYMBOL(dss_mgr_enable);
0231 
0232 void dss_mgr_disable(struct omap_overlay_manager *mgr)
0233 {
0234     dss_mgr_ops->disable(mgr);
0235 }
0236 EXPORT_SYMBOL(dss_mgr_disable);
0237 
0238 void dss_mgr_start_update(struct omap_overlay_manager *mgr)
0239 {
0240     dss_mgr_ops->start_update(mgr);
0241 }
0242 EXPORT_SYMBOL(dss_mgr_start_update);
0243 
0244 int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
0245         void (*handler)(void *), void *data)
0246 {
0247     return dss_mgr_ops->register_framedone_handler(mgr, handler, data);
0248 }
0249 EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
0250 
0251 void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
0252         void (*handler)(void *), void *data)
0253 {
0254     dss_mgr_ops->unregister_framedone_handler(mgr, handler, data);
0255 }
0256 EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);