Laurent Pinchart | 51c1327 | 2012-04-26 13:53:59 +0200 | [diff] [blame^] | 1 | /* |
| 2 | * shmob_drm_backlight.c -- SH Mobile DRM Backlight |
| 3 | * |
| 4 | * Copyright (C) 2012 Renesas Corporation |
| 5 | * |
| 6 | * Laurent Pinchart (laurent.pinchart@ideasonboard.com) |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify |
| 9 | * it under the terms of the GNU General Public License as published by |
| 10 | * the Free Software Foundation; either version 2 of the License, or |
| 11 | * (at your option) any later version. |
| 12 | */ |
| 13 | |
| 14 | #include <linux/backlight.h> |
| 15 | |
| 16 | #include "shmob_drm_backlight.h" |
| 17 | #include "shmob_drm_crtc.h" |
| 18 | #include "shmob_drm_drv.h" |
| 19 | |
| 20 | static int shmob_drm_backlight_update(struct backlight_device *bdev) |
| 21 | { |
| 22 | struct shmob_drm_connector *scon = bl_get_data(bdev); |
| 23 | struct shmob_drm_device *sdev = scon->connector.dev->dev_private; |
| 24 | const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; |
| 25 | int brightness = bdev->props.brightness; |
| 26 | |
| 27 | if (bdev->props.power != FB_BLANK_UNBLANK || |
| 28 | bdev->props.state & BL_CORE_SUSPENDED) |
| 29 | brightness = 0; |
| 30 | |
| 31 | return bdata->set_brightness(brightness); |
| 32 | } |
| 33 | |
| 34 | static int shmob_drm_backlight_get_brightness(struct backlight_device *bdev) |
| 35 | { |
| 36 | struct shmob_drm_connector *scon = bl_get_data(bdev); |
| 37 | struct shmob_drm_device *sdev = scon->connector.dev->dev_private; |
| 38 | const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; |
| 39 | |
| 40 | return bdata->get_brightness(); |
| 41 | } |
| 42 | |
| 43 | static const struct backlight_ops shmob_drm_backlight_ops = { |
| 44 | .options = BL_CORE_SUSPENDRESUME, |
| 45 | .update_status = shmob_drm_backlight_update, |
| 46 | .get_brightness = shmob_drm_backlight_get_brightness, |
| 47 | }; |
| 48 | |
| 49 | void shmob_drm_backlight_dpms(struct shmob_drm_connector *scon, int mode) |
| 50 | { |
| 51 | if (scon->backlight == NULL) |
| 52 | return; |
| 53 | |
| 54 | scon->backlight->props.power = mode == DRM_MODE_DPMS_ON |
| 55 | ? FB_BLANK_UNBLANK : FB_BLANK_POWERDOWN; |
| 56 | backlight_update_status(scon->backlight); |
| 57 | } |
| 58 | |
| 59 | int shmob_drm_backlight_init(struct shmob_drm_connector *scon) |
| 60 | { |
| 61 | struct shmob_drm_device *sdev = scon->connector.dev->dev_private; |
| 62 | const struct shmob_drm_backlight_data *bdata = &sdev->pdata->backlight; |
| 63 | struct drm_connector *connector = &scon->connector; |
| 64 | struct drm_device *dev = connector->dev; |
| 65 | struct backlight_device *backlight; |
| 66 | |
| 67 | if (!bdata->max_brightness) |
| 68 | return 0; |
| 69 | |
| 70 | backlight = backlight_device_register(bdata->name, dev->dev, scon, |
| 71 | &shmob_drm_backlight_ops, NULL); |
| 72 | if (IS_ERR(backlight)) { |
| 73 | dev_err(dev->dev, "unable to register backlight device: %ld\n", |
| 74 | PTR_ERR(backlight)); |
| 75 | return PTR_ERR(backlight); |
| 76 | } |
| 77 | |
| 78 | backlight->props.max_brightness = bdata->max_brightness; |
| 79 | backlight->props.brightness = bdata->max_brightness; |
| 80 | backlight->props.power = FB_BLANK_POWERDOWN; |
| 81 | backlight_update_status(backlight); |
| 82 | |
| 83 | scon->backlight = backlight; |
| 84 | return 0; |
| 85 | } |
| 86 | |
| 87 | void shmob_drm_backlight_exit(struct shmob_drm_connector *scon) |
| 88 | { |
| 89 | backlight_device_unregister(scon->backlight); |
| 90 | } |