Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  LCD / Backlight control code for Sharp SL-6000x (tosa)
0004  *
0005  *  Copyright (c) 2005      Dirk Opfer
0006  *  Copyright (c) 2007,2008 Dmitry Baryshkov
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/module.h>
0011 #include <linux/device.h>
0012 #include <linux/spi/spi.h>
0013 #include <linux/i2c.h>
0014 #include <linux/gpio/consumer.h>
0015 #include <linux/fb.h>
0016 #include <linux/backlight.h>
0017 #include <linux/slab.h>
0018 
0019 #include <asm/mach/sharpsl_param.h>
0020 
0021 #include "tosa_bl.h"
0022 
0023 #define COMADJ_DEFAULT  97
0024 
0025 #define DAC_CH1     0
0026 #define DAC_CH2     1
0027 
0028 struct tosa_bl_data {
0029     struct i2c_client *i2c;
0030     struct backlight_device *bl;
0031     struct gpio_desc *gpio;
0032 
0033     int comadj;
0034 };
0035 
0036 static void tosa_bl_set_backlight(struct tosa_bl_data *data, int brightness)
0037 {
0038     struct spi_device *spi = dev_get_platdata(&data->i2c->dev);
0039 
0040     i2c_smbus_write_byte_data(data->i2c, DAC_CH1, data->comadj);
0041 
0042     /* SetBacklightDuty */
0043     i2c_smbus_write_byte_data(data->i2c, DAC_CH2, (u8)(brightness & 0xff));
0044 
0045     /* SetBacklightVR */
0046     gpiod_set_value(data->gpio, brightness & 0x100);
0047 
0048     tosa_bl_enable(spi, brightness);
0049 }
0050 
0051 static int tosa_bl_update_status(struct backlight_device *dev)
0052 {
0053     struct backlight_properties *props = &dev->props;
0054     struct tosa_bl_data *data = bl_get_data(dev);
0055     int power = max(props->power, props->fb_blank);
0056     int brightness = props->brightness;
0057 
0058     if (power)
0059         brightness = 0;
0060 
0061     tosa_bl_set_backlight(data, brightness);
0062 
0063     return 0;
0064 }
0065 
0066 static int tosa_bl_get_brightness(struct backlight_device *dev)
0067 {
0068     struct backlight_properties *props = &dev->props;
0069 
0070     return props->brightness;
0071 }
0072 
0073 static const struct backlight_ops bl_ops = {
0074     .get_brightness     = tosa_bl_get_brightness,
0075     .update_status      = tosa_bl_update_status,
0076 };
0077 
0078 static int tosa_bl_probe(struct i2c_client *client,
0079         const struct i2c_device_id *id)
0080 {
0081     struct backlight_properties props;
0082     struct tosa_bl_data *data;
0083     int ret = 0;
0084 
0085     data = devm_kzalloc(&client->dev, sizeof(struct tosa_bl_data),
0086                 GFP_KERNEL);
0087     if (!data)
0088         return -ENOMEM;
0089 
0090     data->comadj = sharpsl_param.comadj == -1 ? COMADJ_DEFAULT : sharpsl_param.comadj;
0091     data->gpio = devm_gpiod_get(&client->dev, "backlight", GPIOD_OUT_LOW);
0092     ret = PTR_ERR_OR_ZERO(data->gpio);
0093     if (ret) {
0094         dev_dbg(&data->bl->dev, "Unable to request gpio!\n");
0095         return ret;
0096     }
0097 
0098     i2c_set_clientdata(client, data);
0099     data->i2c = client;
0100 
0101     memset(&props, 0, sizeof(struct backlight_properties));
0102     props.type = BACKLIGHT_RAW;
0103     props.max_brightness = 512 - 1;
0104     data->bl = devm_backlight_device_register(&client->dev, "tosa-bl",
0105                         &client->dev, data, &bl_ops,
0106                         &props);
0107     if (IS_ERR(data->bl)) {
0108         ret = PTR_ERR(data->bl);
0109         goto err_reg;
0110     }
0111 
0112     data->bl->props.brightness = 69;
0113     data->bl->props.power = FB_BLANK_UNBLANK;
0114 
0115     backlight_update_status(data->bl);
0116 
0117     return 0;
0118 
0119 err_reg:
0120     data->bl = NULL;
0121     return ret;
0122 }
0123 
0124 static int tosa_bl_remove(struct i2c_client *client)
0125 {
0126     struct tosa_bl_data *data = i2c_get_clientdata(client);
0127 
0128     data->bl = NULL;
0129     return 0;
0130 }
0131 
0132 #ifdef CONFIG_PM_SLEEP
0133 static int tosa_bl_suspend(struct device *dev)
0134 {
0135     struct tosa_bl_data *data = dev_get_drvdata(dev);
0136 
0137     tosa_bl_set_backlight(data, 0);
0138 
0139     return 0;
0140 }
0141 
0142 static int tosa_bl_resume(struct device *dev)
0143 {
0144     struct tosa_bl_data *data = dev_get_drvdata(dev);
0145 
0146     backlight_update_status(data->bl);
0147     return 0;
0148 }
0149 #endif
0150 
0151 static SIMPLE_DEV_PM_OPS(tosa_bl_pm_ops, tosa_bl_suspend, tosa_bl_resume);
0152 
0153 static const struct i2c_device_id tosa_bl_id[] = {
0154     { "tosa-bl", 0 },
0155     { },
0156 };
0157 MODULE_DEVICE_TABLE(i2c, tosa_bl_id);
0158 
0159 static struct i2c_driver tosa_bl_driver = {
0160     .driver = {
0161         .name       = "tosa-bl",
0162         .pm     = &tosa_bl_pm_ops,
0163     },
0164     .probe      = tosa_bl_probe,
0165     .remove     = tosa_bl_remove,
0166     .id_table   = tosa_bl_id,
0167 };
0168 
0169 module_i2c_driver(tosa_bl_driver);
0170 
0171 MODULE_AUTHOR("Dmitry Baryshkov");
0172 MODULE_LICENSE("GPL v2");
0173 MODULE_DESCRIPTION("LCD/Backlight control for Sharp SL-6000 PDA");
0174