^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) // Copyright (c) 2011 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // http://www.samsung.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) // Common infrastructure for PWM Backlight for Samsung boards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/gpio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pwm_backlight.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "devs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "gpio-cfg.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "backlight-s3c64xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct samsung_bl_drvdata {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) struct platform_pwm_backlight_data plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct samsung_bl_gpio_info *gpio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static int samsung_bl_init(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) struct platform_pwm_backlight_data *pdata = dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct samsung_bl_drvdata *drvdata = container_of(pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct samsung_bl_drvdata, plat_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) ret = gpio_request(bl_gpio_info->no, "Backlight");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) printk(KERN_ERR "failed to request GPIO for LCD Backlight\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Configure GPIO pin with specific GPIO function for PWM timer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) s3c_gpio_cfgpin(bl_gpio_info->no, bl_gpio_info->func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static void samsung_bl_exit(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) struct platform_pwm_backlight_data *pdata = dev->platform_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct samsung_bl_drvdata *drvdata = container_of(pdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) struct samsung_bl_drvdata, plat_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct samsung_bl_gpio_info *bl_gpio_info = drvdata->gpio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) s3c_gpio_cfgpin(bl_gpio_info->no, S3C_GPIO_OUTPUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) gpio_free(bl_gpio_info->no);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) /* Initialize few important fields of platform_pwm_backlight_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * structure with default values. These fields can be overridden by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * board-specific values sent from machine file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * For ease of operation, these fields are initialized with values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * used by most samsung boards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * Users has the option of sending info about other parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * for their specific boards
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static struct samsung_bl_drvdata samsung_dfl_bl_data __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) .plat_data = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) .max_brightness = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) .dft_brightness = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) .init = samsung_bl_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) .exit = samsung_bl_exit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct platform_device samsung_dfl_bl_device __initdata = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) .name = "pwm-backlight",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* samsung_bl_set - Set board specific data (if any) provided by user for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) * PWM Backlight control and register specific PWM and backlight device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * @gpio_info: structure containing GPIO info for PWM timer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * @bl_data: structure containing Backlight control data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void __init samsung_bl_set(struct samsung_bl_gpio_info *gpio_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct platform_pwm_backlight_data *bl_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct platform_device *samsung_bl_device;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) struct samsung_bl_drvdata *samsung_bl_drvdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct platform_pwm_backlight_data *samsung_bl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) samsung_bl_device = kmemdup(&samsung_dfl_bl_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) sizeof(struct platform_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (!samsung_bl_device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) samsung_bl_drvdata = kmemdup(&samsung_dfl_bl_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) sizeof(samsung_dfl_bl_data), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (!samsung_bl_drvdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) goto err_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) samsung_bl_device->dev.platform_data = &samsung_bl_drvdata->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) samsung_bl_drvdata->gpio_info = gpio_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) samsung_bl_data = &samsung_bl_drvdata->plat_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /* Copy board specific data provided by user */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) samsung_bl_device->dev.parent = &samsung_device_pwm.dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (bl_data->max_brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) samsung_bl_data->max_brightness = bl_data->max_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (bl_data->dft_brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) samsung_bl_data->dft_brightness = bl_data->dft_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) if (bl_data->lth_brightness)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) samsung_bl_data->lth_brightness = bl_data->lth_brightness;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (bl_data->init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) samsung_bl_data->init = bl_data->init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (bl_data->notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) samsung_bl_data->notify = bl_data->notify;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (bl_data->notify_after)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) samsung_bl_data->notify_after = bl_data->notify_after;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) if (bl_data->exit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) samsung_bl_data->exit = bl_data->exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (bl_data->check_fb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) samsung_bl_data->check_fb = bl_data->check_fb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Register the Backlight dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ret = platform_device_register(samsung_bl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) printk(KERN_ERR "failed to register backlight device: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) goto err_plat_reg2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) err_plat_reg2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) kfree(samsung_bl_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) err_data:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) kfree(samsung_bl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }