[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20120405192139.GC14821@thinkpad-t410>
Date: Thu, 5 Apr 2012 14:21:39 -0500
From: Seth Forshee <seth.forshee@...onical.com>
To: Akio Idehara <zbe64533@...il.com>
Cc: mjg59@...f.ucam.org, platform-driver-x86@...r.kernel.org,
linux-kernel@...r.kernel.org
Subject: Re: [PATCH v4] toshiba_acpi: Add support for transflective LCD
On Fri, Apr 06, 2012 at 01:46:43AM +0900, Akio Idehara wrote:
> Some Toshiba laptops have the transflective LCD and toshset
> can control its backlight state. I brought this feature to the
> mainline. To support transflective LCD, it's implemented by
> adding an extra level to the backlight and having 0 change to
> transflective mode. It was tested on a Toshiba Portege R500.
>
> Signed-off-by: Akio Idehara <zbe64533@...il.com>
Looks good.
Acked-by: Seth Forshee <seth.forshee@...onical.com>
> ---
> drivers/platform/x86/toshiba_acpi.c | 63 +++++++++++++++++++++++++++++++---
> 1 files changed, 57 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c
> index ee79ce6..cc0641b 100644
> --- a/drivers/platform/x86/toshiba_acpi.c
> +++ b/drivers/platform/x86/toshiba_acpi.c
> @@ -95,6 +95,7 @@ MODULE_LICENSE("GPL");
>
> /* registers */
> #define HCI_FAN 0x0004
> +#define HCI_TR_BACKLIGHT 0x0005
> #define HCI_SYSTEM_EVENT 0x0016
> #define HCI_VIDEO_OUT 0x001c
> #define HCI_HOTKEY_EVENT 0x001e
> @@ -134,6 +135,7 @@ struct toshiba_acpi_dev {
> unsigned int system_event_supported:1;
> unsigned int ntfy_supported:1;
> unsigned int info_supported:1;
> + unsigned int tr_backlight_supported:1;
>
> struct mutex mutex;
> };
> @@ -478,6 +480,25 @@ static const struct rfkill_ops toshiba_rfk_ops = {
> .poll = bt_rfkill_poll,
> };
>
> +static int get_tr_backlight_status(struct toshiba_acpi_dev *dev, bool *enabled)
> +{
> + u32 hci_result;
> + u32 status;
> +
> + hci_read1(dev, HCI_TR_BACKLIGHT, &status, &hci_result);
> + *enabled = !status;
> + return hci_result == HCI_SUCCESS ? 0 : -EIO;
> +}
> +
> +static int set_tr_backlight_status(struct toshiba_acpi_dev *dev, bool enable)
> +{
> + u32 hci_result;
> + u32 value = !enable;
> +
> + hci_write1(dev, HCI_TR_BACKLIGHT, value, &hci_result);
> + return hci_result == HCI_SUCCESS ? 0 : -EIO;
> +}
> +
> static struct proc_dir_entry *toshiba_proc_dir /*= 0*/ ;
>
> static int get_lcd(struct backlight_device *bd)
> @@ -485,10 +506,21 @@ static int get_lcd(struct backlight_device *bd)
> struct toshiba_acpi_dev *dev = bl_get_data(bd);
> u32 hci_result;
> u32 value;
> + int brightness = 0;
> +
> + if (dev->tr_backlight_supported) {
> + bool enabled;
> + int ret = get_tr_backlight_status(dev, &enabled);
> + if (ret)
> + return ret;
> + if (enabled)
> + return 0;
> + brightness++;
> + }
>
> hci_read1(dev, HCI_LCD_BRIGHTNESS, &value, &hci_result);
> if (hci_result == HCI_SUCCESS)
> - return (value >> HCI_LCD_BRIGHTNESS_SHIFT);
> + return brightness + (value >> HCI_LCD_BRIGHTNESS_SHIFT);
>
> return -EIO;
> }
> @@ -497,15 +529,16 @@ static int lcd_proc_show(struct seq_file *m, void *v)
> {
> struct toshiba_acpi_dev *dev = m->private;
> int value;
> + int levels;
>
> if (!dev->backlight_dev)
> return -ENODEV;
>
> + levels = dev->backlight_dev->props.max_brightness + 1;
> value = get_lcd(dev->backlight_dev);
> if (value >= 0) {
> seq_printf(m, "brightness: %d\n", value);
> - seq_printf(m, "brightness_levels: %d\n",
> - HCI_LCD_BRIGHTNESS_LEVELS);
> + seq_printf(m, "brightness_levels: %d\n", levels);
> return 0;
> }
>
> @@ -521,6 +554,14 @@ static int lcd_proc_open(struct inode *inode, struct file *file)
> static int set_lcd(struct toshiba_acpi_dev *dev, int value)
> {
> u32 hci_result;
> + if (dev->tr_backlight_supported) {
> + bool enable = !value;
> + int ret = set_tr_backlight_status(dev, enable);
> + if (ret)
> + return ret;
> + if (value)
> + value--;
> + }
>
> value = value << HCI_LCD_BRIGHTNESS_SHIFT;
> hci_write1(dev, HCI_LCD_BRIGHTNESS, value, &hci_result);
> @@ -541,6 +582,7 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
> size_t len;
> int value;
> int ret;
> + int levels = dev->backlight_dev->props.max_brightness + 1;
>
> len = min(count, sizeof(cmd) - 1);
> if (copy_from_user(cmd, buf, len))
> @@ -548,7 +590,7 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
> cmd[len] = '\0';
>
> if (sscanf(cmd, " brightness : %i", &value) == 1 &&
> - value >= 0 && value < HCI_LCD_BRIGHTNESS_LEVELS) {
> + value >= 0 && value < levels) {
> ret = set_lcd(dev, value);
> if (ret == 0)
> ret = count;
> @@ -860,8 +902,9 @@ static void remove_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
> }
>
> static const struct backlight_ops toshiba_backlight_data = {
> - .get_brightness = get_lcd,
> - .update_status = set_lcd_status,
> + .options = BL_CORE_SUSPENDRESUME,
> + .get_brightness = get_lcd,
> + .update_status = set_lcd_status,
> };
>
> static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str,
> @@ -1079,6 +1122,7 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
> bool bt_present;
> int ret = 0;
> struct backlight_properties props;
> + bool enabled;
>
> if (toshiba_acpi)
> return -EBUSY;
> @@ -1104,8 +1148,15 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev)
>
> mutex_init(&dev->mutex);
>
> + /* Determine whether or not BIOS supports transflective backlight */
> + ret = get_tr_backlight_status(dev, &enabled);
> + dev->tr_backlight_supported = !ret;
> +
> props.type = BACKLIGHT_PLATFORM;
> props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1;
> + /* adding an extra level and having 0 change to transflective mode */
> + if (dev->tr_backlight_supported)
> + props.max_brightness++;
> dev->backlight_dev = backlight_device_register("toshiba",
> &acpi_dev->dev,
> dev,
> --
> 1.7.7.6
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists