diff options
author | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2011-09-11 12:27:50 -0400 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2012-03-12 17:40:45 -0400 |
commit | 8511ea4ad39e351767167280b0b0ac716a8f2986 (patch) | |
tree | 49eb2661f2187f6bcd88c7b35b49c2dc08463e80 | |
parent | d2ccdc807baa38a6487a25099c939a82f4698953 (diff) |
fbdev: sh_mobile_hdmi: Implement sh_mobile_lcdc_entity interface
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
-rw-r--r-- | drivers/video/sh_mobile_hdmi.c | 39 |
1 files changed, 31 insertions, 8 deletions
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index ebd06515f033..5e5f83c31594 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c | |||
@@ -208,6 +208,8 @@ enum hotplug_state { | |||
208 | }; | 208 | }; |
209 | 209 | ||
210 | struct sh_hdmi { | 210 | struct sh_hdmi { |
211 | struct sh_mobile_lcdc_entity entity; | ||
212 | |||
211 | void __iomem *base; | 213 | void __iomem *base; |
212 | enum hotplug_state hp_state; /* hot-plug status */ | 214 | enum hotplug_state hp_state; /* hot-plug status */ |
213 | u8 preprogrammed_vic; /* use a pre-programmed VIC or | 215 | u8 preprogrammed_vic; /* use a pre-programmed VIC or |
@@ -225,6 +227,7 @@ struct sh_hdmi { | |||
225 | struct notifier_block notifier; | 227 | struct notifier_block notifier; |
226 | }; | 228 | }; |
227 | 229 | ||
230 | #define entity_to_sh_hdmi(e) container_of(e, struct sh_hdmi, entity) | ||
228 | #define notifier_to_hdmi(n) container_of(n, struct sh_hdmi, notifier) | 231 | #define notifier_to_hdmi(n) container_of(n, struct sh_hdmi, notifier) |
229 | 232 | ||
230 | static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) | 233 | static void hdmi_write(struct sh_hdmi *hdmi, u8 data, u8 reg) |
@@ -1001,13 +1004,14 @@ static irqreturn_t sh_hdmi_hotplug(int irq, void *dev_id) | |||
1001 | } | 1004 | } |
1002 | 1005 | ||
1003 | /* locking: called with info->lock held, or before register_framebuffer() */ | 1006 | /* locking: called with info->lock held, or before register_framebuffer() */ |
1004 | static void sh_hdmi_display_on(void *arg, struct fb_info *info) | 1007 | static int __sh_hdmi_display_on(struct sh_mobile_lcdc_entity *entity, |
1008 | struct fb_info *info) | ||
1005 | { | 1009 | { |
1006 | /* | 1010 | /* |
1007 | * info is guaranteed to be valid, when we are called, because our | 1011 | * info is guaranteed to be valid, when we are called, because our |
1008 | * FB_EVENT_FB_UNBIND notify is also called with info->lock held | 1012 | * FB_EVENT_FB_UNBIND notify is also called with info->lock held |
1009 | */ | 1013 | */ |
1010 | struct sh_hdmi *hdmi = arg; | 1014 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity); |
1011 | struct sh_mobile_lcdc_chan *ch = info->par; | 1015 | struct sh_mobile_lcdc_chan *ch = info->par; |
1012 | 1016 | ||
1013 | dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state); | 1017 | dev_dbg(hdmi->dev, "%s(%p): state %x\n", __func__, hdmi, info->state); |
@@ -1032,18 +1036,35 @@ static void sh_hdmi_display_on(void *arg, struct fb_info *info) | |||
1032 | default: | 1036 | default: |
1033 | hdmi->var = ch->display_var; | 1037 | hdmi->var = ch->display_var; |
1034 | } | 1038 | } |
1039 | |||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | static void sh_hdmi_display_on(void *arg, struct fb_info *info) | ||
1044 | { | ||
1045 | __sh_hdmi_display_on(arg, info); | ||
1035 | } | 1046 | } |
1036 | 1047 | ||
1037 | /* locking: called with info->lock held */ | 1048 | /* locking: called with info->lock held */ |
1038 | static void sh_hdmi_display_off(void *arg) | 1049 | static void __sh_hdmi_display_off(struct sh_mobile_lcdc_entity *entity) |
1039 | { | 1050 | { |
1040 | struct sh_hdmi *hdmi = arg; | 1051 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(entity); |
1041 | 1052 | ||
1042 | dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi); | 1053 | dev_dbg(hdmi->dev, "%s(%p)\n", __func__, hdmi); |
1043 | /* PS mode e->a */ | 1054 | /* PS mode e->a */ |
1044 | hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); | 1055 | hdmi_write(hdmi, 0x10, HDMI_SYSTEM_CTRL); |
1045 | } | 1056 | } |
1046 | 1057 | ||
1058 | static void sh_hdmi_display_off(void *arg) | ||
1059 | { | ||
1060 | __sh_hdmi_display_off(arg); | ||
1061 | } | ||
1062 | |||
1063 | static const struct sh_mobile_lcdc_entity_ops sh_hdmi_ops = { | ||
1064 | .display_on = __sh_hdmi_display_on, | ||
1065 | .display_off = __sh_hdmi_display_off, | ||
1066 | }; | ||
1067 | |||
1047 | static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) | 1068 | static bool sh_hdmi_must_reconfigure(struct sh_hdmi *hdmi) |
1048 | { | 1069 | { |
1049 | struct fb_info *info = hdmi->info; | 1070 | struct fb_info *info = hdmi->info; |
@@ -1157,7 +1178,7 @@ static void sh_hdmi_edid_work_fn(struct work_struct *work) | |||
1157 | */ | 1178 | */ |
1158 | info->var.width = hdmi->var.width; | 1179 | info->var.width = hdmi->var.width; |
1159 | info->var.height = hdmi->var.height; | 1180 | info->var.height = hdmi->var.height; |
1160 | sh_hdmi_display_on(hdmi, info); | 1181 | __sh_hdmi_display_on(&hdmi->entity, info); |
1161 | } else { | 1182 | } else { |
1162 | /* New monitor or have to wake up */ | 1183 | /* New monitor or have to wake up */ |
1163 | fb_set_suspend(info, 0); | 1184 | fb_set_suspend(info, 0); |
@@ -1251,6 +1272,8 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) | |||
1251 | mutex_init(&hdmi->mutex); | 1272 | mutex_init(&hdmi->mutex); |
1252 | 1273 | ||
1253 | hdmi->dev = &pdev->dev; | 1274 | hdmi->dev = &pdev->dev; |
1275 | hdmi->entity.owner = THIS_MODULE; | ||
1276 | hdmi->entity.ops = &sh_hdmi_ops; | ||
1254 | 1277 | ||
1255 | hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); | 1278 | hdmi->hdmi_clk = clk_get(&pdev->dev, "ick"); |
1256 | if (IS_ERR(hdmi->hdmi_clk)) { | 1279 | if (IS_ERR(hdmi->hdmi_clk)) { |
@@ -1290,12 +1313,12 @@ static int __init sh_hdmi_probe(struct platform_device *pdev) | |||
1290 | goto emap; | 1313 | goto emap; |
1291 | } | 1314 | } |
1292 | 1315 | ||
1293 | platform_set_drvdata(pdev, hdmi); | 1316 | platform_set_drvdata(pdev, &hdmi->entity); |
1294 | 1317 | ||
1295 | /* Set up LCDC callbacks */ | 1318 | /* Set up LCDC callbacks */ |
1296 | board_cfg = &pdata->lcd_chan->board_cfg; | 1319 | board_cfg = &pdata->lcd_chan->board_cfg; |
1297 | board_cfg->owner = THIS_MODULE; | 1320 | board_cfg->owner = THIS_MODULE; |
1298 | board_cfg->board_data = hdmi; | 1321 | board_cfg->board_data = &hdmi->entity; |
1299 | board_cfg->display_on = sh_hdmi_display_on; | 1322 | board_cfg->display_on = sh_hdmi_display_on; |
1300 | board_cfg->display_off = sh_hdmi_display_off; | 1323 | board_cfg->display_off = sh_hdmi_display_off; |
1301 | 1324 | ||
@@ -1349,7 +1372,7 @@ egetclk: | |||
1349 | static int __exit sh_hdmi_remove(struct platform_device *pdev) | 1372 | static int __exit sh_hdmi_remove(struct platform_device *pdev) |
1350 | { | 1373 | { |
1351 | struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; | 1374 | struct sh_mobile_hdmi_info *pdata = pdev->dev.platform_data; |
1352 | struct sh_hdmi *hdmi = platform_get_drvdata(pdev); | 1375 | struct sh_hdmi *hdmi = entity_to_sh_hdmi(platform_get_drvdata(pdev)); |
1353 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1376 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1354 | struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg; | 1377 | struct sh_mobile_lcdc_board_cfg *board_cfg = &pdata->lcd_chan->board_cfg; |
1355 | int irq = platform_get_irq(pdev, 0); | 1378 | int irq = platform_get_irq(pdev, 0); |