PageRenderTime 19ms CodeModel.GetById 10ms app.highlight 7ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/video/backlight/kb3886_bl.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t
C | 209 lines | 157 code | 37 blank | 15 comment | 8 complexity | cbdd6ce55c62f960f5685d561cf912f1 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  1/*
  2 *  Backlight Driver for the KB3886 Backlight
  3 *
  4 *  Copyright (c) 2007-2008 Claudio Nieder
  5 *
  6 *  Based on corgi_bl.c by Richard Purdie and kb3886 driver by Robert Woerle
  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 version 2 as
 10 *  published by the Free Software Foundation.
 11 *
 12 */
 13
 14#include <linux/module.h>
 15#include <linux/kernel.h>
 16#include <linux/init.h>
 17#include <linux/platform_device.h>
 18#include <linux/mutex.h>
 19#include <linux/fb.h>
 20#include <linux/backlight.h>
 21#include <linux/delay.h>
 22#include <linux/dmi.h>
 23
 24#define KB3886_PARENT 0x64
 25#define KB3886_IO 0x60
 26#define KB3886_ADC_DAC_PWM 0xC4
 27#define KB3886_PWM0_WRITE 0x81
 28#define KB3886_PWM0_READ 0x41
 29
 30static DEFINE_MUTEX(bl_mutex);
 31
 32static void kb3886_bl_set_intensity(int intensity)
 33{
 34	mutex_lock(&bl_mutex);
 35	intensity = intensity&0xff;
 36	outb(KB3886_ADC_DAC_PWM, KB3886_PARENT);
 37	msleep(10);
 38	outb(KB3886_PWM0_WRITE, KB3886_IO);
 39	msleep(10);
 40	outb(intensity, KB3886_IO);
 41	mutex_unlock(&bl_mutex);
 42}
 43
 44struct kb3886bl_machinfo {
 45	int max_intensity;
 46	int default_intensity;
 47	int limit_mask;
 48	void (*set_bl_intensity)(int intensity);
 49};
 50
 51static struct kb3886bl_machinfo kb3886_bl_machinfo = {
 52	.max_intensity = 0xff,
 53	.default_intensity = 0xa0,
 54	.limit_mask = 0x7f,
 55	.set_bl_intensity = kb3886_bl_set_intensity,
 56};
 57
 58static struct platform_device kb3886bl_device = {
 59	.name		= "kb3886-bl",
 60	.dev		= {
 61		.platform_data	= &kb3886_bl_machinfo,
 62	},
 63	.id		= -1,
 64};
 65
 66static struct platform_device *devices[] __initdata = {
 67	&kb3886bl_device,
 68};
 69
 70/*
 71 * Back to driver
 72 */
 73
 74static int kb3886bl_intensity;
 75static struct backlight_device *kb3886_backlight_device;
 76static struct kb3886bl_machinfo *bl_machinfo;
 77
 78static unsigned long kb3886bl_flags;
 79#define KB3886BL_SUSPENDED     0x01
 80
 81static struct dmi_system_id __initdata kb3886bl_device_table[] = {
 82	{
 83		.ident = "Sahara Touch-iT",
 84		.matches = {
 85			DMI_MATCH(DMI_SYS_VENDOR, "SDV"),
 86			DMI_MATCH(DMI_PRODUCT_NAME, "iTouch T201"),
 87		},
 88	},
 89	{ }
 90};
 91
 92static int kb3886bl_send_intensity(struct backlight_device *bd)
 93{
 94	int intensity = bd->props.brightness;
 95
 96	if (bd->props.power != FB_BLANK_UNBLANK)
 97		intensity = 0;
 98	if (bd->props.fb_blank != FB_BLANK_UNBLANK)
 99		intensity = 0;
100	if (kb3886bl_flags & KB3886BL_SUSPENDED)
101		intensity = 0;
102
103	bl_machinfo->set_bl_intensity(intensity);
104
105	kb3886bl_intensity = intensity;
106	return 0;
107}
108
109#ifdef CONFIG_PM
110static int kb3886bl_suspend(struct platform_device *pdev, pm_message_t state)
111{
112	struct backlight_device *bd = platform_get_drvdata(pdev);
113
114	kb3886bl_flags |= KB3886BL_SUSPENDED;
115	backlight_update_status(bd);
116	return 0;
117}
118
119static int kb3886bl_resume(struct platform_device *pdev)
120{
121	struct backlight_device *bd = platform_get_drvdata(pdev);
122
123	kb3886bl_flags &= ~KB3886BL_SUSPENDED;
124	backlight_update_status(bd);
125	return 0;
126}
127#else
128#define kb3886bl_suspend	NULL
129#define kb3886bl_resume		NULL
130#endif
131
132static int kb3886bl_get_intensity(struct backlight_device *bd)
133{
134	return kb3886bl_intensity;
135}
136
137static const struct backlight_ops kb3886bl_ops = {
138	.get_brightness = kb3886bl_get_intensity,
139	.update_status  = kb3886bl_send_intensity,
140};
141
142static int kb3886bl_probe(struct platform_device *pdev)
143{
144	struct backlight_properties props;
145	struct kb3886bl_machinfo *machinfo = pdev->dev.platform_data;
146
147	bl_machinfo = machinfo;
148	if (!machinfo->limit_mask)
149		machinfo->limit_mask = -1;
150
151	memset(&props, 0, sizeof(struct backlight_properties));
152	props.type = BACKLIGHT_RAW;
153	props.max_brightness = machinfo->max_intensity;
154	kb3886_backlight_device = backlight_device_register("kb3886-bl",
155							    &pdev->dev, NULL,
156							    &kb3886bl_ops,
157							    &props);
158	if (IS_ERR(kb3886_backlight_device))
159		return PTR_ERR(kb3886_backlight_device);
160
161	platform_set_drvdata(pdev, kb3886_backlight_device);
162
163	kb3886_backlight_device->props.power = FB_BLANK_UNBLANK;
164	kb3886_backlight_device->props.brightness = machinfo->default_intensity;
165	backlight_update_status(kb3886_backlight_device);
166
167	return 0;
168}
169
170static int kb3886bl_remove(struct platform_device *pdev)
171{
172	struct backlight_device *bd = platform_get_drvdata(pdev);
173
174	backlight_device_unregister(bd);
175
176	return 0;
177}
178
179static struct platform_driver kb3886bl_driver = {
180	.probe		= kb3886bl_probe,
181	.remove		= kb3886bl_remove,
182	.suspend	= kb3886bl_suspend,
183	.resume		= kb3886bl_resume,
184	.driver		= {
185		.name	= "kb3886-bl",
186	},
187};
188
189static int __init kb3886_init(void)
190{
191	if (!dmi_check_system(kb3886bl_device_table))
192		return -ENODEV;
193
194	platform_add_devices(devices, ARRAY_SIZE(devices));
195	return platform_driver_register(&kb3886bl_driver);
196}
197
198static void __exit kb3886_exit(void)
199{
200	platform_driver_unregister(&kb3886bl_driver);
201}
202
203module_init(kb3886_init);
204module_exit(kb3886_exit);
205
206MODULE_AUTHOR("Claudio Nieder <private@claudio.ch>");
207MODULE_DESCRIPTION("Tabletkiosk Sahara Touch-iT Backlight Driver");
208MODULE_LICENSE("GPL");
209MODULE_ALIAS("dmi:*:svnSDV:pniTouchT201:*");