Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.11-rc6 382 lines 9.8 kB view raw
1/* 2 * Copyright (C) 2012 Texas Instruments 3 * Author: Rob Clark <robdclark@gmail.com> 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 as published by 7 * the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * You should have received a copy of the GNU General Public License along with 15 * this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18#include <linux/i2c.h> 19#include <linux/of_i2c.h> 20#include <linux/pinctrl/pinmux.h> 21#include <linux/pinctrl/consumer.h> 22#include <drm/drm_encoder_slave.h> 23 24#include "tilcdc_drv.h" 25 26struct slave_module { 27 struct tilcdc_module base; 28 struct i2c_adapter *i2c; 29}; 30#define to_slave_module(x) container_of(x, struct slave_module, base) 31 32static const struct tilcdc_panel_info slave_info = { 33 .bpp = 16, 34 .ac_bias = 255, 35 .ac_bias_intrpt = 0, 36 .dma_burst_sz = 16, 37 .fdd = 0x80, 38 .tft_alt_mode = 0, 39 .sync_edge = 0, 40 .sync_ctrl = 1, 41 .raster_order = 0, 42}; 43 44 45/* 46 * Encoder: 47 */ 48 49struct slave_encoder { 50 struct drm_encoder_slave base; 51 struct slave_module *mod; 52}; 53#define to_slave_encoder(x) container_of(to_encoder_slave(x), struct slave_encoder, base) 54 55static inline struct drm_encoder_slave_funcs * 56get_slave_funcs(struct drm_encoder *enc) 57{ 58 return to_encoder_slave(enc)->slave_funcs; 59} 60 61static void slave_encoder_destroy(struct drm_encoder *encoder) 62{ 63 struct slave_encoder *slave_encoder = to_slave_encoder(encoder); 64 if (get_slave_funcs(encoder)) 65 get_slave_funcs(encoder)->destroy(encoder); 66 drm_encoder_cleanup(encoder); 67 kfree(slave_encoder); 68} 69 70static void slave_encoder_prepare(struct drm_encoder *encoder) 71{ 72 drm_i2c_encoder_prepare(encoder); 73 tilcdc_crtc_set_panel_info(encoder->crtc, &slave_info); 74} 75 76static const struct drm_encoder_funcs slave_encoder_funcs = { 77 .destroy = slave_encoder_destroy, 78}; 79 80static const struct drm_encoder_helper_funcs slave_encoder_helper_funcs = { 81 .dpms = drm_i2c_encoder_dpms, 82 .mode_fixup = drm_i2c_encoder_mode_fixup, 83 .prepare = slave_encoder_prepare, 84 .commit = drm_i2c_encoder_commit, 85 .mode_set = drm_i2c_encoder_mode_set, 86 .save = drm_i2c_encoder_save, 87 .restore = drm_i2c_encoder_restore, 88}; 89 90static const struct i2c_board_info info = { 91 I2C_BOARD_INFO("tda998x", 0x70) 92}; 93 94static struct drm_encoder *slave_encoder_create(struct drm_device *dev, 95 struct slave_module *mod) 96{ 97 struct slave_encoder *slave_encoder; 98 struct drm_encoder *encoder; 99 int ret; 100 101 slave_encoder = kzalloc(sizeof(*slave_encoder), GFP_KERNEL); 102 if (!slave_encoder) { 103 dev_err(dev->dev, "allocation failed\n"); 104 return NULL; 105 } 106 107 slave_encoder->mod = mod; 108 109 encoder = &slave_encoder->base.base; 110 encoder->possible_crtcs = 1; 111 112 ret = drm_encoder_init(dev, encoder, &slave_encoder_funcs, 113 DRM_MODE_ENCODER_TMDS); 114 if (ret) 115 goto fail; 116 117 drm_encoder_helper_add(encoder, &slave_encoder_helper_funcs); 118 119 ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), mod->i2c, &info); 120 if (ret) 121 goto fail; 122 123 return encoder; 124 125fail: 126 slave_encoder_destroy(encoder); 127 return NULL; 128} 129 130/* 131 * Connector: 132 */ 133 134struct slave_connector { 135 struct drm_connector base; 136 137 struct drm_encoder *encoder; /* our connected encoder */ 138 struct slave_module *mod; 139}; 140#define to_slave_connector(x) container_of(x, struct slave_connector, base) 141 142static void slave_connector_destroy(struct drm_connector *connector) 143{ 144 struct slave_connector *slave_connector = to_slave_connector(connector); 145 drm_connector_cleanup(connector); 146 kfree(slave_connector); 147} 148 149static enum drm_connector_status slave_connector_detect( 150 struct drm_connector *connector, 151 bool force) 152{ 153 struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 154 return get_slave_funcs(encoder)->detect(encoder, connector); 155} 156 157static int slave_connector_get_modes(struct drm_connector *connector) 158{ 159 struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 160 return get_slave_funcs(encoder)->get_modes(encoder, connector); 161} 162 163static int slave_connector_mode_valid(struct drm_connector *connector, 164 struct drm_display_mode *mode) 165{ 166 struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 167 struct tilcdc_drm_private *priv = connector->dev->dev_private; 168 int ret; 169 170 ret = tilcdc_crtc_mode_valid(priv->crtc, mode); 171 if (ret != MODE_OK) 172 return ret; 173 174 return get_slave_funcs(encoder)->mode_valid(encoder, mode); 175} 176 177static struct drm_encoder *slave_connector_best_encoder( 178 struct drm_connector *connector) 179{ 180 struct slave_connector *slave_connector = to_slave_connector(connector); 181 return slave_connector->encoder; 182} 183 184static int slave_connector_set_property(struct drm_connector *connector, 185 struct drm_property *property, uint64_t value) 186{ 187 struct drm_encoder *encoder = to_slave_connector(connector)->encoder; 188 return get_slave_funcs(encoder)->set_property(encoder, 189 connector, property, value); 190} 191 192static const struct drm_connector_funcs slave_connector_funcs = { 193 .destroy = slave_connector_destroy, 194 .dpms = drm_helper_connector_dpms, 195 .detect = slave_connector_detect, 196 .fill_modes = drm_helper_probe_single_connector_modes, 197 .set_property = slave_connector_set_property, 198}; 199 200static const struct drm_connector_helper_funcs slave_connector_helper_funcs = { 201 .get_modes = slave_connector_get_modes, 202 .mode_valid = slave_connector_mode_valid, 203 .best_encoder = slave_connector_best_encoder, 204}; 205 206static struct drm_connector *slave_connector_create(struct drm_device *dev, 207 struct slave_module *mod, struct drm_encoder *encoder) 208{ 209 struct slave_connector *slave_connector; 210 struct drm_connector *connector; 211 int ret; 212 213 slave_connector = kzalloc(sizeof(*slave_connector), GFP_KERNEL); 214 if (!slave_connector) { 215 dev_err(dev->dev, "allocation failed\n"); 216 return NULL; 217 } 218 219 slave_connector->encoder = encoder; 220 slave_connector->mod = mod; 221 222 connector = &slave_connector->base; 223 224 drm_connector_init(dev, connector, &slave_connector_funcs, 225 DRM_MODE_CONNECTOR_HDMIA); 226 drm_connector_helper_add(connector, &slave_connector_helper_funcs); 227 228 connector->polled = DRM_CONNECTOR_POLL_CONNECT | 229 DRM_CONNECTOR_POLL_DISCONNECT; 230 231 connector->interlace_allowed = 0; 232 connector->doublescan_allowed = 0; 233 234 get_slave_funcs(encoder)->create_resources(encoder, connector); 235 236 ret = drm_mode_connector_attach_encoder(connector, encoder); 237 if (ret) 238 goto fail; 239 240 drm_sysfs_connector_add(connector); 241 242 return connector; 243 244fail: 245 slave_connector_destroy(connector); 246 return NULL; 247} 248 249/* 250 * Module: 251 */ 252 253static int slave_modeset_init(struct tilcdc_module *mod, struct drm_device *dev) 254{ 255 struct slave_module *slave_mod = to_slave_module(mod); 256 struct tilcdc_drm_private *priv = dev->dev_private; 257 struct drm_encoder *encoder; 258 struct drm_connector *connector; 259 260 encoder = slave_encoder_create(dev, slave_mod); 261 if (!encoder) 262 return -ENOMEM; 263 264 connector = slave_connector_create(dev, slave_mod, encoder); 265 if (!connector) 266 return -ENOMEM; 267 268 priv->encoders[priv->num_encoders++] = encoder; 269 priv->connectors[priv->num_connectors++] = connector; 270 271 return 0; 272} 273 274static void slave_destroy(struct tilcdc_module *mod) 275{ 276 struct slave_module *slave_mod = to_slave_module(mod); 277 278 tilcdc_module_cleanup(mod); 279 kfree(slave_mod); 280} 281 282static const struct tilcdc_module_ops slave_module_ops = { 283 .modeset_init = slave_modeset_init, 284 .destroy = slave_destroy, 285}; 286 287/* 288 * Device: 289 */ 290 291static struct of_device_id slave_of_match[]; 292 293static int slave_probe(struct platform_device *pdev) 294{ 295 struct device_node *node = pdev->dev.of_node; 296 struct device_node *i2c_node; 297 struct slave_module *slave_mod; 298 struct tilcdc_module *mod; 299 struct pinctrl *pinctrl; 300 uint32_t i2c_phandle; 301 struct i2c_adapter *slavei2c; 302 int ret = -EINVAL; 303 304 /* bail out early if no DT data: */ 305 if (!node) { 306 dev_err(&pdev->dev, "device-tree data is missing\n"); 307 return -ENXIO; 308 } 309 310 /* Bail out early if i2c not specified */ 311 if (of_property_read_u32(node, "i2c", &i2c_phandle)) { 312 dev_err(&pdev->dev, "could not get i2c bus phandle\n"); 313 return ret; 314 } 315 316 i2c_node = of_find_node_by_phandle(i2c_phandle); 317 if (!i2c_node) { 318 dev_err(&pdev->dev, "could not get i2c bus node\n"); 319 return ret; 320 } 321 322 /* but defer the probe if it can't be initialized it might come later */ 323 slavei2c = of_find_i2c_adapter_by_node(i2c_node); 324 of_node_put(i2c_node); 325 326 if (!slavei2c) { 327 ret = -EPROBE_DEFER; 328 tilcdc_slave_probedefer(true); 329 dev_err(&pdev->dev, "could not get i2c\n"); 330 return ret; 331 } 332 333 slave_mod = kzalloc(sizeof(*slave_mod), GFP_KERNEL); 334 if (!slave_mod) 335 return -ENOMEM; 336 337 mod = &slave_mod->base; 338 339 mod->preferred_bpp = slave_info.bpp; 340 341 slave_mod->i2c = slavei2c; 342 343 tilcdc_module_init(mod, "slave", &slave_module_ops); 344 345 pinctrl = devm_pinctrl_get_select_default(&pdev->dev); 346 if (IS_ERR(pinctrl)) 347 dev_warn(&pdev->dev, "pins are not configured\n"); 348 349 tilcdc_slave_probedefer(false); 350 351 return 0; 352} 353 354static int slave_remove(struct platform_device *pdev) 355{ 356 return 0; 357} 358 359static struct of_device_id slave_of_match[] = { 360 { .compatible = "ti,tilcdc,slave", }, 361 { }, 362}; 363 364struct platform_driver slave_driver = { 365 .probe = slave_probe, 366 .remove = slave_remove, 367 .driver = { 368 .owner = THIS_MODULE, 369 .name = "slave", 370 .of_match_table = slave_of_match, 371 }, 372}; 373 374int __init tilcdc_slave_init(void) 375{ 376 return platform_driver_register(&slave_driver); 377} 378 379void __exit tilcdc_slave_fini(void) 380{ 381 platform_driver_unregister(&slave_driver); 382}