This converts the da8xx fbdev driver to use GPIO backlight device

and regulator devices. This will finally help get rid of legacy
 GPIO API calls and simplify DaVinci GPIO driver.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQIcBAABAgAGBQJdZpeCAAoJEGFBu2jqvgRNx/wQAI/7q9NQ+BxhFKMYuL78khjh
 vAmysYdy81ZPF7rfyBnE7zLrjJF1wAFMEWKQfSIWETxmTac3wH0EQYe2urGSfPsT
 XgFasrN3cZ8ElSznWdftUxAA8+QGdl+cHAkOCnlVLEfYRdIed8KZhfMHSl1UXLTk
 Cj/DgTg1Sk65Uj+1XDo/bOKxRHH+5U6HrNZOQdLqlkGRZppVXlKFIxG5loo6XsHE
 y8h6jKQD6PVr2a1VdR8OjfENhCyPUQzz7UUBM2E8DNKe/EXnSSBVss5JFePEXOY+
 +QpLvHRKBk8yZmraIlDnoetGKC74sikGvtaFPNQoZ4Q2+kf/+t8Asni5wjJyX4wz
 0sy/tGk8MmpE1PgevfNc+9Tk3TiqRa7pqlAgCZ36CBpinpOulxWxrLuQV2JJvmLm
 kHHKAi1lJM5tp/WrDr8vFAmS4LX7Zoosd+x2Q4TyNNE/NvJyhizyZTQZM4JRzTQG
 gyiPnjIfinuip6vWIxCsKw8li2QXdG1ShBUYXkTN/0g33XHOcUnCWjqxPjK6/0GW
 mmMQg4Zou8q5W/9AfOfYUqLehGlG89eYAx3YymHavgdCva+SBv8Xb7c3CpcWRm3A
 bRg2FRHK5DpTCmEUt91snF4cdVidOcrWZt04IO4Sl8JUQKOBGPmVNiNY3r22v5T+
 qTClFIj07nDunCEwW+wR
 =GdvX
 -----END PGP SIGNATURE-----

Merge tag 'davinci-for-v5.4/fbdev' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci into arm/drivers

This converts the da8xx fbdev driver to use GPIO backlight device
and regulator devices. This will finally help get rid of legacy
GPIO API calls and simplify DaVinci GPIO driver.

* tag 'davinci-for-v5.4/fbdev' of git://git.kernel.org/pub/scm/linux/kernel/git/nsekhar/linux-davinci:
  fbdev: da8xx: use resource management for dma
  fbdev: da8xx-fb: drop a redundant if
  fbdev: da8xx-fb: use devm_platform_ioremap_resource()
  fbdev: da8xx: remove panel_power_ctrl() callback from platform data
  ARM: davinci: da850-evm: switch to using a fixed regulator for lcdc
  fbdev: da8xx: add support for a regulator
  ARM: davinci: da850-evm: model the backlight GPIO as an actual device

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2019-09-04 16:55:52 +02:00
commit 735f013110
3 changed files with 135 additions and 82 deletions

View File

@ -36,6 +36,7 @@
#include <linux/platform_data/ti-aemif.h>
#include <linux/platform_data/spi-davinci.h>
#include <linux/platform_data/uio_pruss.h>
#include <linux/property.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/tps6507x.h>
#include <linux/regulator/fixed.h>
@ -802,38 +803,80 @@ static const short da850_evm_mmcsd0_pins[] __initconst = {
-1
};
static void da850_panel_power_ctrl(int val)
{
/* lcd backlight */
gpio_set_value(DA850_LCD_BL_PIN, val);
static struct property_entry da850_lcd_backlight_props[] = {
PROPERTY_ENTRY_BOOL("default-on"),
{ }
};
/* lcd power */
gpio_set_value(DA850_LCD_PWR_PIN, val);
}
static struct gpiod_lookup_table da850_lcd_backlight_gpio_table = {
.dev_id = "gpio-backlight",
.table = {
GPIO_LOOKUP("davinci_gpio", DA850_LCD_BL_PIN, NULL, 0),
{ }
},
};
static const struct platform_device_info da850_lcd_backlight_info = {
.name = "gpio-backlight",
.id = PLATFORM_DEVID_NONE,
.properties = da850_lcd_backlight_props,
};
static struct regulator_consumer_supply da850_lcd_supplies[] = {
REGULATOR_SUPPLY("lcd", NULL),
};
static struct regulator_init_data da850_lcd_supply_data = {
.consumer_supplies = da850_lcd_supplies,
.num_consumer_supplies = ARRAY_SIZE(da850_lcd_supplies),
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
},
};
static struct fixed_voltage_config da850_lcd_supply = {
.supply_name = "lcd",
.microvolts = 33000000,
.init_data = &da850_lcd_supply_data,
};
static struct platform_device da850_lcd_supply_device = {
.name = "reg-fixed-voltage",
.id = 1, /* Dummy fixed regulator is 0 */
.dev = {
.platform_data = &da850_lcd_supply,
},
};
static struct gpiod_lookup_table da850_lcd_supply_gpio_table = {
.dev_id = "reg-fixed-voltage.1",
.table = {
GPIO_LOOKUP("davinci_gpio", DA850_LCD_PWR_PIN, NULL, 0),
{ }
},
};
static struct gpiod_lookup_table *da850_lcd_gpio_lookups[] = {
&da850_lcd_backlight_gpio_table,
&da850_lcd_supply_gpio_table,
};
static int da850_lcd_hw_init(void)
{
struct platform_device *backlight;
int status;
status = gpio_request(DA850_LCD_BL_PIN, "lcd bl");
if (status < 0)
gpiod_add_lookup_tables(da850_lcd_gpio_lookups,
ARRAY_SIZE(da850_lcd_gpio_lookups));
backlight = platform_device_register_full(&da850_lcd_backlight_info);
if (IS_ERR(backlight))
return PTR_ERR(backlight);
status = platform_device_register(&da850_lcd_supply_device);
if (status)
return status;
status = gpio_request(DA850_LCD_PWR_PIN, "lcd pwr");
if (status < 0) {
gpio_free(DA850_LCD_BL_PIN);
return status;
}
gpio_direction_output(DA850_LCD_BL_PIN, 0);
gpio_direction_output(DA850_LCD_PWR_PIN, 0);
/* Switch off panel power and backlight */
da850_panel_power_ctrl(0);
/* Switch on panel power and backlight */
da850_panel_power_ctrl(1);
return 0;
}
@ -1443,7 +1486,6 @@ static __init void da850_evm_init(void)
if (ret)
pr_warn("%s: LCD initialization failed: %d\n", __func__, ret);
sharp_lk043t1dg01_pdata.panel_power_ctrl = da850_panel_power_ctrl,
ret = da8xx_register_lcdc(&sharp_lk043t1dg01_pdata);
if (ret)
pr_warn("%s: LCDC registration failed: %d\n", __func__, ret);

View File

@ -19,6 +19,7 @@
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/console.h>
#include <linux/regulator/consumer.h>
#include <linux/spinlock.h>
#include <linux/slab.h>
#include <linux/delay.h>
@ -164,7 +165,7 @@ struct da8xx_fb_par {
struct notifier_block freq_transition;
#endif
unsigned int lcdc_clk_rate;
void (*panel_power_ctrl)(int);
struct regulator *lcd_supply;
u32 pseudo_palette[16];
struct fb_videomode mode;
struct lcd_ctrl_config cfg;
@ -1066,33 +1067,30 @@ static void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par)
static int fb_remove(struct platform_device *dev)
{
struct fb_info *info = dev_get_drvdata(&dev->dev);
if (info) {
struct da8xx_fb_par *par = info->par;
struct da8xx_fb_par *par = info->par;
int ret;
#ifdef CONFIG_CPU_FREQ
lcd_da8xx_cpufreq_deregister(par);
lcd_da8xx_cpufreq_deregister(par);
#endif
if (par->panel_power_ctrl)
par->panel_power_ctrl(0);
lcd_disable_raster(DA8XX_FRAME_WAIT);
lcdc_write(0, LCD_RASTER_CTRL_REG);
/* disable DMA */
lcdc_write(0, LCD_DMA_CTRL_REG);
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
dma_free_coherent(par->dev, PALETTE_SIZE, par->v_palette_base,
par->p_palette_base);
dma_free_coherent(par->dev, par->vram_size, par->vram_virt,
par->vram_phys);
pm_runtime_put_sync(&dev->dev);
pm_runtime_disable(&dev->dev);
framebuffer_release(info);
if (par->lcd_supply) {
ret = regulator_disable(par->lcd_supply);
if (ret)
return ret;
}
lcd_disable_raster(DA8XX_FRAME_WAIT);
lcdc_write(0, LCD_RASTER_CTRL_REG);
/* disable DMA */
lcdc_write(0, LCD_DMA_CTRL_REG);
unregister_framebuffer(info);
fb_dealloc_cmap(&info->cmap);
pm_runtime_put_sync(&dev->dev);
pm_runtime_disable(&dev->dev);
framebuffer_release(info);
return 0;
}
@ -1179,15 +1177,21 @@ static int cfb_blank(int blank, struct fb_info *info)
case FB_BLANK_UNBLANK:
lcd_enable_raster();
if (par->panel_power_ctrl)
par->panel_power_ctrl(1);
if (par->lcd_supply) {
ret = regulator_enable(par->lcd_supply);
if (ret)
return ret;
}
break;
case FB_BLANK_NORMAL:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_POWERDOWN:
if (par->panel_power_ctrl)
par->panel_power_ctrl(0);
if (par->lcd_supply) {
ret = regulator_disable(par->lcd_supply);
if (ret)
return ret;
}
lcd_disable_raster(DA8XX_FRAME_WAIT);
break;
@ -1328,7 +1332,6 @@ static int fb_probe(struct platform_device *device)
{
struct da8xx_lcdc_platform_data *fb_pdata =
dev_get_platdata(&device->dev);
struct resource *lcdc_regs;
struct lcd_ctrl_config *lcd_cfg;
struct fb_videomode *lcdc_info;
struct fb_info *da8xx_fb_info;
@ -1346,8 +1349,7 @@ static int fb_probe(struct platform_device *device)
if (lcdc_info == NULL)
return -ENODEV;
lcdc_regs = platform_get_resource(device, IORESOURCE_MEM, 0);
da8xx_fb_reg_base = devm_ioremap_resource(&device->dev, lcdc_regs);
da8xx_fb_reg_base = devm_platform_ioremap_resource(device, 0);
if (IS_ERR(da8xx_fb_reg_base))
return PTR_ERR(da8xx_fb_reg_base);
@ -1395,9 +1397,19 @@ static int fb_probe(struct platform_device *device)
par->dev = &device->dev;
par->lcdc_clk = tmp_lcdc_clk;
par->lcdc_clk_rate = clk_get_rate(par->lcdc_clk);
if (fb_pdata->panel_power_ctrl) {
par->panel_power_ctrl = fb_pdata->panel_power_ctrl;
par->panel_power_ctrl(1);
par->lcd_supply = devm_regulator_get_optional(&device->dev, "lcd");
if (IS_ERR(par->lcd_supply)) {
if (PTR_ERR(par->lcd_supply) == -EPROBE_DEFER) {
ret = -EPROBE_DEFER;
goto err_pm_runtime_disable;
}
par->lcd_supply = NULL;
} else {
ret = regulator_enable(par->lcd_supply);
if (ret)
goto err_pm_runtime_disable;
}
fb_videomode_to_var(&da8xx_fb_var, lcdc_info);
@ -1411,10 +1423,10 @@ static int fb_probe(struct platform_device *device)
par->vram_size = roundup(par->vram_size/8, ulcm);
par->vram_size = par->vram_size * LCD_NUM_BUFFERS;
par->vram_virt = dma_alloc_coherent(par->dev,
par->vram_size,
&par->vram_phys,
GFP_KERNEL | GFP_DMA);
par->vram_virt = dmam_alloc_coherent(par->dev,
par->vram_size,
&par->vram_phys,
GFP_KERNEL | GFP_DMA);
if (!par->vram_virt) {
dev_err(&device->dev,
"GLCD: kmalloc for frame buffer failed\n");
@ -1432,20 +1444,20 @@ static int fb_probe(struct platform_device *device)
da8xx_fb_fix.line_length - 1;
/* allocate palette buffer */
par->v_palette_base = dma_alloc_coherent(par->dev, PALETTE_SIZE,
&par->p_palette_base,
GFP_KERNEL | GFP_DMA);
par->v_palette_base = dmam_alloc_coherent(par->dev, PALETTE_SIZE,
&par->p_palette_base,
GFP_KERNEL | GFP_DMA);
if (!par->v_palette_base) {
dev_err(&device->dev,
"GLCD: kmalloc for palette buffer failed\n");
ret = -EINVAL;
goto err_release_fb_mem;
goto err_release_fb;
}
par->irq = platform_get_irq(device, 0);
if (par->irq < 0) {
ret = -ENOENT;
goto err_release_pl_mem;
goto err_release_fb;
}
da8xx_fb_var.grayscale =
@ -1463,7 +1475,7 @@ static int fb_probe(struct platform_device *device)
ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0);
if (ret)
goto err_release_pl_mem;
goto err_release_fb;
da8xx_fb_info->cmap.len = par->palette_sz;
/* initialize var_screeninfo */
@ -1517,14 +1529,6 @@ static int fb_probe(struct platform_device *device)
err_dealloc_cmap:
fb_dealloc_cmap(&da8xx_fb_info->cmap);
err_release_pl_mem:
dma_free_coherent(par->dev, PALETTE_SIZE, par->v_palette_base,
par->p_palette_base);
err_release_fb_mem:
dma_free_coherent(par->dev, par->vram_size, par->vram_virt,
par->vram_phys);
err_release_fb:
framebuffer_release(da8xx_fb_info);
@ -1603,10 +1607,14 @@ static int fb_suspend(struct device *dev)
{
struct fb_info *info = dev_get_drvdata(dev);
struct da8xx_fb_par *par = info->par;
int ret;
console_lock();
if (par->panel_power_ctrl)
par->panel_power_ctrl(0);
if (par->lcd_supply) {
ret = regulator_disable(par->lcd_supply);
if (ret)
return ret;
}
fb_set_suspend(info, 1);
lcd_disable_raster(DA8XX_FRAME_WAIT);
@ -1620,6 +1628,7 @@ static int fb_resume(struct device *dev)
{
struct fb_info *info = dev_get_drvdata(dev);
struct da8xx_fb_par *par = info->par;
int ret;
console_lock();
pm_runtime_get_sync(dev);
@ -1627,8 +1636,11 @@ static int fb_resume(struct device *dev)
if (par->blank == FB_BLANK_UNBLANK) {
lcd_enable_raster();
if (par->panel_power_ctrl)
par->panel_power_ctrl(1);
if (par->lcd_supply) {
ret = regulator_enable(par->lcd_supply);
if (ret)
return ret;
}
}
fb_set_suspend(info, 0);

View File

@ -32,7 +32,6 @@ struct da8xx_lcdc_platform_data {
const char manu_name[10];
void *controller_data;
const char type[25];
void (*panel_power_ctrl)(int);
};
struct lcd_ctrl_config {