aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorThomas Niederprüm <niederp@physik.uni-kl.de>2015-03-31 14:27:15 -0400
committerTomi Valkeinen <tomi.valkeinen@ti.com>2015-05-27 05:54:37 -0400
commit6ed5e2db52b1e27a70241ef8749780f6f5d553bf (patch)
tree01ad7125f44f0161aaa9545689db7c4b0bd1b049 /drivers/video
parent13bad59730c31e876588977534b6b6a46ce876ae (diff)
fbdev: ssd1307fb: add backlight controls for setting the contrast
The backlight class is used to create userspace handles for setting the OLED contrast. Signed-off-by: Thomas Niederprüm <niederp@physik.uni-kl.de> Acked-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/Kconfig1
-rw-r--r--drivers/video/fbdev/ssd1307fb.c58
2 files changed, 59 insertions, 0 deletions
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 109462303087..54fb8f86b68d 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -2478,6 +2478,7 @@ config FB_SSD1307
2478 select FB_SYS_IMAGEBLIT 2478 select FB_SYS_IMAGEBLIT
2479 select FB_DEFERRED_IO 2479 select FB_DEFERRED_IO
2480 select PWM 2480 select PWM
2481 select FB_BACKLIGHT
2481 help 2482 help
2482 This driver implements support for the Solomon SSD1307 2483 This driver implements support for the Solomon SSD1307
2483 OLED controller over I2C. 2484 OLED controller over I2C.
diff --git a/drivers/video/fbdev/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index 5f3d5a810c54..77efed7a42a3 100644
--- a/drivers/video/fbdev/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
@@ -7,6 +7,7 @@
7 */ 7 */
8 8
9#include <linux/module.h> 9#include <linux/module.h>
10#include <linux/backlight.h>
10#include <linux/kernel.h> 11#include <linux/kernel.h>
11#include <linux/i2c.h> 12#include <linux/i2c.h>
12#include <linux/fb.h> 13#include <linux/fb.h>
@@ -38,6 +39,8 @@
38#define SSD1307FB_SET_COM_PINS_CONFIG 0xda 39#define SSD1307FB_SET_COM_PINS_CONFIG 0xda
39#define SSD1307FB_SET_VCOMH 0xdb 40#define SSD1307FB_SET_VCOMH 0xdb
40 41
42#define MAX_CONTRAST 255
43
41#define REFRESHRATE 1 44#define REFRESHRATE 1
42 45
43static u_int refreshrate = REFRESHRATE; 46static u_int refreshrate = REFRESHRATE;
@@ -424,6 +427,43 @@ static int ssd1307fb_init(struct ssd1307fb_par *par)
424 return 0; 427 return 0;
425} 428}
426 429
430static int ssd1307fb_update_bl(struct backlight_device *bdev)
431{
432 struct ssd1307fb_par *par = bl_get_data(bdev);
433 int ret;
434 int brightness = bdev->props.brightness;
435
436 par->contrast = brightness;
437
438 ret = ssd1307fb_write_cmd(par->client, SSD1307FB_CONTRAST);
439 if (ret < 0)
440 return ret;
441 ret = ssd1307fb_write_cmd(par->client, par->contrast);
442 if (ret < 0)
443 return ret;
444 return 0;
445}
446
447static int ssd1307fb_get_brightness(struct backlight_device *bdev)
448{
449 struct ssd1307fb_par *par = bl_get_data(bdev);
450
451 return par->contrast;
452}
453
454static int ssd1307fb_check_fb(struct backlight_device *bdev,
455 struct fb_info *info)
456{
457 return (info->bl_dev == bdev);
458}
459
460static const struct backlight_ops ssd1307fb_bl_ops = {
461 .options = BL_CORE_SUSPENDRESUME,
462 .update_status = ssd1307fb_update_bl,
463 .get_brightness = ssd1307fb_get_brightness,
464 .check_fb = ssd1307fb_check_fb,
465};
466
427static struct ssd1307fb_deviceinfo ssd1307fb_ssd1305_deviceinfo = { 467static struct ssd1307fb_deviceinfo ssd1307fb_ssd1305_deviceinfo = {
428 .default_vcomh = 0x34, 468 .default_vcomh = 0x34,
429 .default_dclk_div = 1, 469 .default_dclk_div = 1,
@@ -464,6 +504,8 @@ MODULE_DEVICE_TABLE(of, ssd1307fb_of_match);
464static int ssd1307fb_probe(struct i2c_client *client, 504static int ssd1307fb_probe(struct i2c_client *client,
465 const struct i2c_device_id *id) 505 const struct i2c_device_id *id)
466{ 506{
507 struct backlight_device *bl;
508 char bl_name[12];
467 struct fb_info *info; 509 struct fb_info *info;
468 struct device_node *node = client->dev.of_node; 510 struct device_node *node = client->dev.of_node;
469 struct fb_deferred_io *ssd1307fb_defio; 511 struct fb_deferred_io *ssd1307fb_defio;
@@ -599,10 +641,24 @@ static int ssd1307fb_probe(struct i2c_client *client,
599 goto panel_init_error; 641 goto panel_init_error;
600 } 642 }
601 643
644 snprintf(bl_name, sizeof(bl_name), "ssd1307fb%d", info->node);
645 bl = backlight_device_register(bl_name, &client->dev, par,
646 &ssd1307fb_bl_ops, NULL);
647 bl->props.brightness = par->contrast;
648 bl->props.max_brightness = MAX_CONTRAST;
649 info->bl_dev = bl;
650
651 if (IS_ERR(bl)) {
652 dev_err(&client->dev, "unable to register backlight device: %ld\n",
653 PTR_ERR(bl));
654 goto bl_init_error;
655 }
602 dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size); 656 dev_info(&client->dev, "fb%d: %s framebuffer device registered, using %d bytes of video memory\n", info->node, info->fix.id, vmem_size);
603 657
604 return 0; 658 return 0;
605 659
660bl_init_error:
661 unregister_framebuffer(info);
606panel_init_error: 662panel_init_error:
607 if (par->device_info->need_pwm) { 663 if (par->device_info->need_pwm) {
608 pwm_disable(par->pwm); 664 pwm_disable(par->pwm);
@@ -622,6 +678,8 @@ static int ssd1307fb_remove(struct i2c_client *client)
622 678
623 ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF); 679 ssd1307fb_write_cmd(par->client, SSD1307FB_DISPLAY_OFF);
624 680
681 backlight_device_unregister(info->bl_dev);
682
625 unregister_framebuffer(info); 683 unregister_framebuffer(info);
626 if (par->device_info->need_pwm) { 684 if (par->device_info->need_pwm) {
627 pwm_disable(par->pwm); 685 pwm_disable(par->pwm);