📄 corgi_lcd.c
字号:
/* (6)Set PDWN, INIOFF, DACOFF */ corgi_ssp_lcdtg_send(lcd, PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF | PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF); /* (7)DAC OFF */ corgi_ssp_lcdtg_send(lcd, POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF); /* (8)VDD OFF */ corgi_ssp_lcdtg_send(lcd, POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);}static int corgi_lcd_set_mode(struct lcd_device *ld, struct fb_videomode *m){ struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); int mode = CORGI_LCD_MODE_QVGA; if (m->xres == 640 || m->xres == 480) mode = CORGI_LCD_MODE_VGA; if (lcd->mode == mode) return 0; lcdtg_set_phadadj(lcd, mode); switch (mode) { case CORGI_LCD_MODE_VGA: corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_VGA); break; case CORGI_LCD_MODE_QVGA: default: corgi_ssp_lcdtg_send(lcd, RESCTL_ADRS, RESCTL_QVGA); break; } lcd->mode = mode; return 0;}static int corgi_lcd_set_power(struct lcd_device *ld, int power){ struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); if (POWER_IS_ON(power) && !POWER_IS_ON(lcd->power)) corgi_lcd_power_on(lcd); if (!POWER_IS_ON(power) && POWER_IS_ON(lcd->power)) corgi_lcd_power_off(lcd); lcd->power = power; return 0;}static int corgi_lcd_get_power(struct lcd_device *ld){ struct corgi_lcd *lcd = dev_get_drvdata(&ld->dev); return lcd->power;}static struct lcd_ops corgi_lcd_ops = { .get_power = corgi_lcd_get_power, .set_power = corgi_lcd_set_power, .set_mode = corgi_lcd_set_mode,};static int corgi_bl_get_intensity(struct backlight_device *bd){ struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); return lcd->intensity;}static int corgi_bl_set_intensity(struct corgi_lcd *lcd, int intensity){ int cont; if (intensity > 0x10) intensity += 0x10; corgi_ssp_lcdtg_send(lcd, DUTYCTRL_ADRS, intensity); /* Bit 5 via GPIO_BACKLIGHT_CONT */ cont = !!(intensity & 0x20) ^ lcd->gpio_backlight_cont_inverted; if (gpio_is_valid(lcd->gpio_backlight_cont)) gpio_set_value(lcd->gpio_backlight_cont, cont); if (gpio_is_valid(lcd->gpio_backlight_on)) gpio_set_value(lcd->gpio_backlight_on, intensity); if (lcd->kick_battery) lcd->kick_battery(); lcd->intensity = intensity; return 0;}static int corgi_bl_update_status(struct backlight_device *bd){ struct corgi_lcd *lcd = dev_get_drvdata(&bd->dev); int intensity = bd->props.brightness; if (bd->props.power != FB_BLANK_UNBLANK) intensity = 0; if (bd->props.fb_blank != FB_BLANK_UNBLANK) intensity = 0; if (corgibl_flags & CORGIBL_SUSPENDED) intensity = 0; if (corgibl_flags & CORGIBL_BATTLOW) intensity &= lcd->limit_mask; return corgi_bl_set_intensity(lcd, intensity);}void corgi_lcd_limit_intensity(int limit){ if (limit) corgibl_flags |= CORGIBL_BATTLOW; else corgibl_flags &= ~CORGIBL_BATTLOW; backlight_update_status(the_corgi_lcd->bl_dev);}EXPORT_SYMBOL(corgi_lcd_limit_intensity);static struct backlight_ops corgi_bl_ops = { .get_brightness = corgi_bl_get_intensity, .update_status = corgi_bl_update_status,};#ifdef CONFIG_PMstatic int corgi_lcd_suspend(struct spi_device *spi, pm_message_t state){ struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); corgibl_flags |= CORGIBL_SUSPENDED; corgi_bl_set_intensity(lcd, 0); corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); return 0;}static int corgi_lcd_resume(struct spi_device *spi){ struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); corgibl_flags &= ~CORGIBL_SUSPENDED; corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); backlight_update_status(lcd->bl_dev); return 0;}#else#define corgi_lcd_suspend NULL#define corgi_lcd_resume NULL#endifstatic int setup_gpio_backlight(struct corgi_lcd *lcd, struct corgi_lcd_platform_data *pdata){ struct spi_device *spi = lcd->spi_dev; int err; lcd->gpio_backlight_on = -1; lcd->gpio_backlight_cont = -1; if (gpio_is_valid(pdata->gpio_backlight_on)) { err = gpio_request(pdata->gpio_backlight_on, "BL_ON"); if (err) { dev_err(&spi->dev, "failed to request GPIO%d for " "backlight_on\n", pdata->gpio_backlight_on); return err; } lcd->gpio_backlight_on = pdata->gpio_backlight_on; gpio_direction_output(lcd->gpio_backlight_on, 0); } if (gpio_is_valid(pdata->gpio_backlight_cont)) { err = gpio_request(pdata->gpio_backlight_cont, "BL_CONT"); if (err) { dev_err(&spi->dev, "failed to request GPIO%d for " "backlight_cont\n", pdata->gpio_backlight_cont); goto err_free_backlight_on; } lcd->gpio_backlight_cont = pdata->gpio_backlight_cont; /* spitz and akita use both GPIOs for backlight, and * have inverted polarity of GPIO_BACKLIGHT_CONT */ if (gpio_is_valid(lcd->gpio_backlight_on)) { lcd->gpio_backlight_cont_inverted = 1; gpio_direction_output(lcd->gpio_backlight_cont, 1); } else { lcd->gpio_backlight_cont_inverted = 0; gpio_direction_output(lcd->gpio_backlight_cont, 0); } } return 0;err_free_backlight_on: if (gpio_is_valid(lcd->gpio_backlight_on)) gpio_free(lcd->gpio_backlight_on); return err;}static int __devinit corgi_lcd_probe(struct spi_device *spi){ struct corgi_lcd_platform_data *pdata = spi->dev.platform_data; struct corgi_lcd *lcd; int ret = 0; if (pdata == NULL) { dev_err(&spi->dev, "platform data not available\n"); return -EINVAL; } lcd = kzalloc(sizeof(struct corgi_lcd), GFP_KERNEL); if (!lcd) { dev_err(&spi->dev, "failed to allocate memory\n"); return -ENOMEM; } lcd->spi_dev = spi; lcd->lcd_dev = lcd_device_register("corgi_lcd", &spi->dev, lcd, &corgi_lcd_ops); if (IS_ERR(lcd->lcd_dev)) { ret = PTR_ERR(lcd->lcd_dev); goto err_free_lcd; } lcd->power = FB_BLANK_POWERDOWN; lcd->mode = (pdata) ? pdata->init_mode : CORGI_LCD_MODE_VGA; lcd->bl_dev = backlight_device_register("corgi_bl", &spi->dev, lcd, &corgi_bl_ops); if (IS_ERR(lcd->bl_dev)) { ret = PTR_ERR(lcd->bl_dev); goto err_unregister_lcd; } lcd->bl_dev->props.max_brightness = pdata->max_intensity; lcd->bl_dev->props.brightness = pdata->default_intensity; lcd->bl_dev->props.power = FB_BLANK_UNBLANK; ret = setup_gpio_backlight(lcd, pdata); if (ret) goto err_unregister_bl; lcd->kick_battery = pdata->kick_battery; dev_set_drvdata(&spi->dev, lcd); corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_UNBLANK); backlight_update_status(lcd->bl_dev); lcd->limit_mask = pdata->limit_mask; the_corgi_lcd = lcd; return 0;err_unregister_bl: backlight_device_unregister(lcd->bl_dev);err_unregister_lcd: lcd_device_unregister(lcd->lcd_dev);err_free_lcd: kfree(lcd); return ret;}static int __devexit corgi_lcd_remove(struct spi_device *spi){ struct corgi_lcd *lcd = dev_get_drvdata(&spi->dev); lcd->bl_dev->props.power = FB_BLANK_UNBLANK; lcd->bl_dev->props.brightness = 0; backlight_update_status(lcd->bl_dev); backlight_device_unregister(lcd->bl_dev); if (gpio_is_valid(lcd->gpio_backlight_on)) gpio_free(lcd->gpio_backlight_on); if (gpio_is_valid(lcd->gpio_backlight_cont)) gpio_free(lcd->gpio_backlight_cont); corgi_lcd_set_power(lcd->lcd_dev, FB_BLANK_POWERDOWN); lcd_device_unregister(lcd->lcd_dev); kfree(lcd); return 0;}static struct spi_driver corgi_lcd_driver = { .driver = { .name = "corgi-lcd", .owner = THIS_MODULE, }, .probe = corgi_lcd_probe, .remove = __devexit_p(corgi_lcd_remove), .suspend = corgi_lcd_suspend, .resume = corgi_lcd_resume,};static int __init corgi_lcd_init(void){ return spi_register_driver(&corgi_lcd_driver);}module_init(corgi_lcd_init);static void __exit corgi_lcd_exit(void){ spi_unregister_driver(&corgi_lcd_driver);}module_exit(corgi_lcd_exit);MODULE_DESCRIPTION("LCD and backlight driver for SHARP C7x0/Cxx00");MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -