rockbox/firmware/target/arm/imx233/samsung-ypz5/backlight-ypz5.c

150 lines
4.6 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2013 by Lorenzo Miori
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
#include "config.h"
#include "system.h"
#include "lcd.h"
#include "backlight.h"
#include "backlight-target.h"
#include "pinctrl-imx233.h"
/**
* AAT3151 Backlight Controller
*/
/* Timings */
#define TIME_OFF 500
#define TIME_LOW 50
#define TIME_HI 50
#define TIME_LAT 500
/* Number of raising edges to select the particular register */
#define D1_D4_CURRENT_E 17
#define D1_D3_CURRENT_E 18
#define D4_CURRENT_E 19
#define MAX_CURRENT_E 20
#define LOW_CURRENT_E 21
/* The actual register address / number */
#define D1_D4_CURRENT 1
#define D1_D3_CURRENT 2
#define D4_CURRENT 3
#define MAX_CURRENT 4
#define LOW_CURRENT 5
/* Valid values for LOW_CURRENT register */
#define MAX_CURRENT_20 1
#define MAX_CURRENT_30 2
#define MAX_CURRENT_15 3
#define MAX_CURRENT_LOW_CURRENT 4
static int current_level = -1;
static void create_raising_edges(int num)
{
while (num--)
{
/* Setting a register takes a sufficient small amount of time,
* in the order of 50 ns. Thus the necessary 2 delays TIME_LOW/TIME_HI
* are not strictly necessary */
imx233_pinctrl_set_gpio(3, 13, false);
imx233_pinctrl_set_gpio(3, 13, true);
}
}
static void aat3151_write(int addr, int data)
{
create_raising_edges(16 + addr);
udelay(TIME_LAT);
create_raising_edges(data);
udelay(TIME_LAT);
}
void backlight_hw_brightness(int level)
{
/* Don't try to reset backlight if not necessary
* Moreover this helps to avoid flickering when
* being in some screens like USB mode and
* pressing some keys / touchpad...
*/
if (current_level == level) return;
/* Check for limits and adjust in case */
level = MIN(MAX_BRIGHTNESS_SETTING, MAX(0, level));
if (level == 0)
{
/* Set pin low for a sufficient time, puts the device into low-power consumption state
* In other words backlight goes off
*/
imx233_pinctrl_set_gpio(3, 13, false);
udelay(TIME_OFF);
}
else
{
if (level > 3) {
/* This enables 16 levels of backlight */
aat3151_write(MAX_CURRENT, MAX_CURRENT_15);
/* Set the value according Table 1 in datasheet
* For MAX_CURRENT_15, the scale is from 0 mA to 15 mA in 16 steps
*/
aat3151_write(D1_D3_CURRENT, 19 - level);
}
else {
/* This enables other 4 levels of backlight */
aat3151_write(MAX_CURRENT, MAX_CURRENT_LOW_CURRENT);
/* Set the value according Table 1 in datasheet
* For LOW_CURRENT, there is no "real" scale. We have scattered values.
* We are interested in the last 3 -> 0.5 mA; 1 mA; 2 mA
*/
aat3151_write(LOW_CURRENT, 13 + level);
}
}
current_level = level;
}
bool backlight_hw_init(void)
{
imx233_pinctrl_acquire(3, 13, "backlight");
imx233_pinctrl_set_function(3, 13, PINCTRL_FUNCTION_GPIO);
imx233_pinctrl_set_drive(3, 13, PINCTRL_DRIVE_4mA);
imx233_pinctrl_enable_gpio(3, 13, true);
imx233_pinctrl_set_gpio(3, 13, false);
return true;
}
void backlight_hw_on(void)
{
#ifdef HAVE_LCD_ENABLE
lcd_enable(true); /* power on lcd + visible display */
#endif
/* restore the previous backlight level */
backlight_hw_brightness(backlight_brightness);
}
void backlight_hw_off(void)
{
/* there is no real on/off but we can set to 0 brightness */
backlight_hw_brightness(0);
#ifdef HAVE_LCD_ENABLE
lcd_enable(false); /* power off visible display */
#endif
}