]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge remote-tracking branch 'fbdev/for-next'
authorStephen Rothwell <sfr@canb.auug.org.au>
Fri, 27 Sep 2013 03:50:30 +0000 (13:50 +1000)
committerStephen Rothwell <sfr@canb.auug.org.au>
Fri, 27 Sep 2013 03:50:30 +0000 (13:50 +1000)
1  2 
arch/avr32/boards/atngw100/mrmt.c
arch/avr32/mach-at32ap/at32ap700x.c
drivers/video/Kconfig
drivers/video/atmel_lcdfb.c

Simple merge
Simple merge
Simple merge
index 088511a58a269abc2126f90969a08f3d75a5b22c,ece49d53145a575cebd058c0a0259c7f57614d9f..bf9c5d0ff78eedd69996739bb07ae96b4534151e
@@@ -908,10 -960,181 +960,181 @@@ static void atmel_lcdfb_start_clock(str
  
  static void atmel_lcdfb_stop_clock(struct atmel_lcdfb_info *sinfo)
  {
 -      clk_disable(sinfo->bus_clk);
 -      clk_disable(sinfo->lcdc_clk);
 +      clk_disable_unprepare(sinfo->bus_clk);
 +      clk_disable_unprepare(sinfo->lcdc_clk);
  }
  
+ #ifdef CONFIG_OF
+ static const struct of_device_id atmel_lcdfb_dt_ids[] = {
+       { .compatible = "atmel,at91sam9261-lcdc" , .data = &at91sam9261_config, },
+       { .compatible = "atmel,at91sam9263-lcdc" , .data = &at91sam9263_config, },
+       { .compatible = "atmel,at91sam9g10-lcdc" , .data = &at91sam9g10_config, },
+       { .compatible = "atmel,at91sam9g45-lcdc" , .data = &at91sam9g45_config, },
+       { .compatible = "atmel,at91sam9g45es-lcdc" , .data = &at91sam9g45es_config, },
+       { .compatible = "atmel,at91sam9rl-lcdc" , .data = &at91sam9rl_config, },
+       { .compatible = "atmel,at32ap-lcdc" , .data = &at32ap_config, },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, atmel_lcdfb_dt_ids);
+ static const char *atmel_lcdfb_wiring_modes[] = {
+       [ATMEL_LCDC_WIRING_BGR] = "BRG",
+       [ATMEL_LCDC_WIRING_RGB] = "RGB",
+ };
+ const int atmel_lcdfb_get_of_wiring_modes(struct device_node *np)
+ {
+       const char *mode;
+       int err, i;
+       err = of_property_read_string(np, "atmel,lcd-wiring-mode", &mode);
+       if (err < 0)
+               return ATMEL_LCDC_WIRING_BGR;
+       for (i = 0; i < ARRAY_SIZE(atmel_lcdfb_wiring_modes); i++)
+               if (!strcasecmp(mode, atmel_lcdfb_wiring_modes[i]))
+                       return i;
+       return -ENODEV;
+ }
+ static void atmel_lcdfb_power_control_gpio(struct atmel_lcdfb_pdata *pdata, int on)
+ {
+       struct atmel_lcdfb_power_ctrl_gpio *og;
+       list_for_each_entry(og, &pdata->pwr_gpios, list)
+               gpio_set_value(og->gpio, on);
+ }
+ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
+ {
+       struct fb_info *info = sinfo->info;
+       struct atmel_lcdfb_pdata *pdata = &sinfo->pdata;
+       struct fb_var_screeninfo *var = &info->var;
+       struct device *dev = &sinfo->pdev->dev;
+       struct device_node *np =dev->of_node;
+       struct device_node *display_np;
+       struct device_node *timings_np;
+       struct display_timings *timings;
+       enum of_gpio_flags flags;
+       struct atmel_lcdfb_power_ctrl_gpio *og;
+       bool is_gpio_power = false;
+       int ret = -ENOENT;
+       int i, gpio;
+       sinfo->config = (struct atmel_lcdfb_config*)
+               of_match_device(atmel_lcdfb_dt_ids, dev)->data;
+       display_np = of_parse_phandle(np, "display", 0);
+       if (!display_np) {
+               dev_err(dev, "failed to find display phandle\n");
+               return -ENOENT;
+       }
+       ret = of_property_read_u32(display_np, "bits-per-pixel", &var->bits_per_pixel);
+       if (ret < 0) {
+               dev_err(dev, "failed to get property bits-per-pixel\n");
+               goto put_display_node;
+       }
+       ret = of_property_read_u32(display_np, "atmel,guard-time", &pdata->guard_time);
+       if (ret < 0) {
+               dev_err(dev, "failed to get property atmel,guard-time\n");
+               goto put_display_node;
+       }
+       ret = of_property_read_u32(display_np, "atmel,lcdcon2", &pdata->default_lcdcon2);
+       if (ret < 0) {
+               dev_err(dev, "failed to get property atmel,lcdcon2\n");
+               goto put_display_node;
+       }
+       ret = of_property_read_u32(display_np, "atmel,dmacon", &pdata->default_dmacon);
+       if (ret < 0) {
+               dev_err(dev, "failed to get property bits-per-pixel\n");
+               goto put_display_node;
+       }
+       ret = -ENOMEM;
+       for (i = 0; i < of_gpio_named_count(display_np, "atmel,power-control-gpio"); i++) {
+               gpio = of_get_named_gpio_flags(display_np, "atmel,power-control-gpio",
+                                              i, &flags);
+               if (gpio < 0)
+                       continue;
+               og = devm_kzalloc(dev, sizeof(*og), GFP_KERNEL);
+               if (!og)
+                       goto put_display_node;
+               og->gpio = gpio;
+               og->active_low = flags & OF_GPIO_ACTIVE_LOW;
+               is_gpio_power = true;
+               ret = devm_gpio_request(dev, gpio, "lcd-power-control-gpio");
+               if (ret) {
+                       dev_err(dev, "request gpio %d failed\n", gpio);
+                       goto put_display_node;
+               }
+               ret = gpio_direction_output(gpio, og->active_low);
+               if (ret) {
+                       dev_err(dev, "set direction output gpio %d failed\n", gpio);
+                       goto put_display_node;
+               }
+       }
+       if (is_gpio_power)
+               pdata->atmel_lcdfb_power_control = atmel_lcdfb_power_control_gpio;
+       ret = atmel_lcdfb_get_of_wiring_modes(display_np);
+       if (ret < 0) {
+               dev_err(dev, "invalid atmel,lcd-wiring-mode\n");
+               goto put_display_node;
+       }
+       pdata->lcd_wiring_mode = ret;
+       pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
+       timings = of_get_display_timings(display_np);
+       if (!timings) {
+               dev_err(dev, "failed to get display timings\n");
+               goto put_display_node;
+       }
+       timings_np = of_find_node_by_name(display_np, "display-timings");
+       if (!timings_np) {
+               dev_err(dev, "failed to find display-timings node\n");
+               goto put_display_node;
+       }
+       for (i = 0; i < of_get_child_count(timings_np); i++) {
+               struct videomode vm;
+               struct fb_videomode fb_vm;
+               ret = videomode_from_timings(timings, &vm, i);
+               if (ret < 0)
+                       goto put_timings_node;
+               ret = fb_videomode_from_videomode(&vm, &fb_vm);
+               if (ret < 0)
+                       goto put_timings_node;
+               fb_add_videomode(&fb_vm, &info->modelist);
+       }
+       return 0;
+ put_timings_node:
+       of_node_put(timings_np);
+ put_display_node:
+       of_node_put(display_np);
+       return ret;
+ }
+ #else
+ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
+ {
+       return 0;
+ }
+ #endif
  
  static int __init atmel_lcdfb_probe(struct platform_device *pdev)
  {