static void ktd2026_reset(void)
{
	int retval;
	struct i2c_client *client;
	client = b_client;

	ktd2026_leds_on(LED_R, LED_EN_OFF, 0);
	ktd2026_leds_on(LED_G, LED_EN_OFF, 0);
	ktd2026_leds_on(LED_B, LED_EN_OFF, 0);
	retval = leds_i2c_write_all(client);
	if (retval)
		pr_err("%s:leds_i2c_write_all failed\n", __func__);

	ktd2026_set_timerslot_control(0); /* Tslot1 */
	ktd2026_set_period(0);
	ktd2026_set_pwm_duty(PWM1, 0);
	ktd2026_set_pwm_duty(PWM2, 0);
	ktd2026_set_trise_tfall(0, 0, 0);

	/* get into sleep mode after turing off all the leds */
	ktd2026_set_sleep(1);

	retval = leds_i2c_write_all(client);
	if (retval)
		pr_err("%s:leds_i2c_write_all failed\n", __func__);

	/* reset sleep mode, so that next i2c command
		would not make the driver IC go into sleep mode */
	ktd2026_set_sleep(0);
}
static ssize_t store_led_b(struct device *dev,
	struct device_attribute *devattr, const char *buf, size_t count)
{
	struct ktd2026_data *data = dev_get_drvdata(dev);
	char buff[10] = {0,};
	int cnt, ret;
	u8 brightness;

	cnt = count;
	cnt = (buf[cnt-1] == '\n') ? cnt-1 : cnt;
	memcpy(buff, buf, cnt);
	buff[cnt] = '\0';

	ret = kstrtou8(buff, 0, &brightness);
	if (ret != 0) {
		dev_err(&data->client->dev, "fail to get brightness.\n");
		goto out;
	}

	if (brightness == 0)
		ktd2026_leds_on(LED_B, LED_EN_OFF, 0);
	else
		ktd2026_leds_on(LED_B, LED_EN_ON, brightness);

	leds_i2c_write_all(data->client);
out:
	return count;

}
void ktd2026_led_blink(int rgb, int on, int off)
{
	unsigned int led_brightness = rgb;
	unsigned int delay_on_time = on;
	unsigned int delay_off_time = off;

	u8 led_r_brightness = 0;
	u8 led_g_brightness = 0;
	u8 led_b_brightness = 0;

	/*Reset ktd2026*/
	ktd2026_start_led_pattern(LED_OFF);

	/*Set LED blink mode*/
	led_r_brightness = ((u32)led_brightness & LED_R_MASK) >> LED_R_SHIFT;
	led_g_brightness = ((u32)led_brightness & LED_G_MASK) >> LED_G_SHIFT;
	led_b_brightness = ((u32)led_brightness & LED_B_MASK);

	ktd2026_set_led_blink(LED_R, delay_on_time,
			delay_off_time, led_r_brightness);
	ktd2026_set_led_blink(LED_G, delay_on_time,
			delay_off_time, led_g_brightness);
	ktd2026_set_led_blink(LED_B, delay_on_time,
			delay_off_time, led_b_brightness);

	leds_i2c_write_all(b_client);

	pr_info("%s:led_blink is called, Color:0x%X Brightness:%i\n",
		__func__, led_brightness, led_dynamic_current);
}
static void an30259a_led_brightness_work(struct work_struct *work)
{
		struct i2c_client *client = b_client;
		struct an30259a_led *led = container_of(work,
				struct an30259a_led, brightness_work);
		leds_on(led->channel, true, false, led->brightness);
		leds_i2c_write_all(client);
}
static void ktd2026_led_brightness_work(struct work_struct *work)
{
		struct i2c_client *client = b_client;
		struct ktd2026_led *led = container_of(work,
				struct ktd2026_led, brightness_work);
		if (led->brightness==0)
			ktd2026_leds_on(led->channel, LED_EN_OFF, 0);
		else ktd2026_leds_on(led->channel, LED_EN_ON, led->brightness);

		leds_i2c_write_all(client);
}
static void an30259a_reset_register_work(struct work_struct *work)
{
	int retval;
	struct i2c_client *client;
	client = b_client;

	leds_on(LED_R, false, false, 0);
	leds_on(LED_G, false, false, 0);
	leds_on(LED_B, false, false, 0);

	retval = leds_i2c_write_all(client);
	if (retval)
		printk(KERN_WARNING "leds_i2c_write_all failed\n");
}
static ssize_t store_ktd2026_led_blink(struct device *dev,
					struct device_attribute *devattr,
					const char *buf, size_t count)
{
	/* ex) echo 0x201000 2000 500 > led_blink */
	/* brightness r=20 g=10 b=00, ontime=2000ms, offtime=500ms */
	/* minimum timeunit  of 500ms */

	int retval;
	unsigned int led_brightness = 0;
	unsigned int delay_on_time = 0;
	unsigned int delay_off_time = 0;
	struct ktd2026_data *data = dev_get_drvdata(dev);
	u8 led_r_brightness = 0;
	u8 led_g_brightness = 0;
	u8 led_b_brightness = 0;

	retval = sscanf(buf, "0x%x %d %d", &led_brightness,
		&delay_on_time, &delay_off_time);

	if (retval == 0) {
		dev_err(&data->client->dev, "fail to get led_blink value.\n");
		return count;
	}
	/*Reset ktd2026*/
	ktd2026_start_led_pattern(LED_OFF);

	/*Set LED blink mode*/
	led_r_brightness = ((u32)led_brightness & LED_R_MASK) >> LED_R_SHIFT;
	led_g_brightness = ((u32)led_brightness & LED_G_MASK) >> LED_G_SHIFT;
	led_b_brightness = ((u32)led_brightness & LED_B_MASK);

	ktd2026_set_led_blink(LED_R, delay_on_time,
			delay_off_time, led_r_brightness);
	ktd2026_set_led_blink(LED_G, delay_on_time,
			delay_off_time, led_g_brightness);
	ktd2026_set_led_blink(LED_B, delay_on_time,
			delay_off_time, led_b_brightness);

	leds_i2c_write_all(data->client);

	pr_info("%s:led_blink is called, Color:0x%X Brightness:%i\n",
			__func__, led_brightness, led_dynamic_current);

	return count;
}
static ssize_t store_an30259a_led_blink(struct device *dev,
					struct device_attribute *devattr,
					const char *buf, size_t count)
{
	int retval;
	unsigned int led_brightness = 0;
	unsigned int delay_on_time = 0;
	unsigned int delay_off_time = 0;
	struct an30259a_data *data = dev_get_drvdata(dev);
	u8 led_r_brightness = 0;
	u8 led_g_brightness = 0;
	u8 led_b_brightness = 0;
	struct work_struct *reset = 0;

	retval = sscanf(buf, "0x%x %d %d", &led_brightness,
				&delay_on_time, &delay_off_time);

	if (retval == 0) {
		dev_err(&data->client->dev, "fail to get led_blink value.\n");
		return count;
	}
	/*Reset an30259a*/
	an30259a_reset_register_work(reset);

	/*Set LED blink mode*/
	led_r_brightness = ((u32)led_brightness & LED_R_MASK)
					>> LED_R_SHIFT;
	led_g_brightness = ((u32)led_brightness & LED_G_MASK)
					>> LED_G_SHIFT;
	led_b_brightness = ((u32)led_brightness & LED_B_MASK);

	an30259a_set_led_blink(LED_R, delay_on_time,
				delay_off_time, led_r_brightness);
	an30259a_set_led_blink(LED_G, delay_on_time,
				delay_off_time, led_g_brightness);
	an30259a_set_led_blink(LED_B, delay_on_time,
				delay_off_time, led_b_brightness);

	leds_i2c_write_all(data->client);

	printk(KERN_DEBUG "led_blink is called, Color:0x%X Brightness:%i\n",
			led_brightness, LED_DYNAMIC_CURRENT);

	return count;
}
static ssize_t store_an30259a_led_blink(struct device *dev,
					struct device_attribute *devattr,
					const char *buf, size_t count)
{
	int retval;
	unsigned int led_brightness = 0;
	unsigned int delay_on_time = 0;
	unsigned int delay_off_time = 0;
	struct an30259a_data *data = dev_get_drvdata(dev);
	u8 led_r_brightness = 0;
	u8 led_g_brightness = 0;
	u8 led_b_brightness = 0;

	retval = sscanf(buf, "0x%x %d %d", &led_brightness,
				&delay_on_time, &delay_off_time);

	if (retval == 0) {
		dev_err(&data->client->dev, "fail to get led_blink value.\n");
		return count;
	}
	/*Reset an30259a*/
	an30259a_start_led_pattern(LED_OFF);

	/*Set LED blink mode*/
	led_r_brightness = ((u32)led_brightness & LED_R_MASK)
					>> LED_R_SHIFT;
	led_g_brightness = ((u32)led_brightness & LED_G_MASK)
					>> LED_G_SHIFT;
	led_b_brightness = ((u32)led_brightness & LED_B_MASK);

	an30259a_set_led_blink(LED_R, delay_on_time,
				delay_off_time, led_r_brightness);
	an30259a_set_led_blink(LED_G, delay_on_time,
				delay_off_time, led_g_brightness);
	an30259a_set_led_blink(LED_B, delay_on_time,
				delay_off_time, led_b_brightness);

	leds_i2c_write_all(data->client);

	return count;
}
static int __devinit ktd2026_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct ktd2026_data *data;
	int ret, i;

	pr_info("%s\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "need I2C_FUNC_I2C.\n");
		return -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "need I2C_FUNC_SMBUS_BYTE_DATA.\n");
		return -EIO;
	}

	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data) {
		dev_err(&client->adapter->dev,
			"failed to allocate driver data.\n");
		return -ENOMEM;
	}

	i2c_set_clientdata(client, data);
	data->client = client;
	b_client = client;

	mutex_init(&data->mutex);

	/* initialize LED */
	/* turn off all leds */
	ktd2026_leds_on(LED_R, LED_EN_OFF, 0);
	ktd2026_leds_on(LED_G, LED_EN_OFF, 0);
	ktd2026_leds_on(LED_B, LED_EN_OFF, 0);

	ktd2026_set_timerslot_control(0); /* Tslot1 */
	ktd2026_set_period(0);
	ktd2026_set_pwm_duty(PWM1, 0);
	ktd2026_set_pwm_duty(PWM2, 0);
	ktd2026_set_trise_tfall(0, 0, 0);

	for (i = 0; i < MAX_NUM_LEDS; i++) {

		ret = initialize_channel(client, &data->leds[i], i);

		if (ret < 0) {
			dev_err(&client->adapter->dev, "failure on initialization\n");
			goto exit;
		}
		INIT_WORK(&(data->leds[i].brightness_work),
				 ktd2026_led_brightness_work);
	}

	leds_i2c_write_all(client);

#ifdef SEC_LED_SPECIFIC
	led_dev = device_create(sec_class, NULL, 0, data, "led");
	if (IS_ERR(led_dev)) {
		dev_err(&client->dev,
			"Failed to create device for samsung specific led\n");
		ret = -ENODEV;
		goto exit;
	}
	ret = sysfs_create_group(&led_dev->kobj, &sec_led_attr_group);
	if (ret) {
		dev_err(&client->dev,
			"Failed to create sysfs group for samsung specific led\n");
		device_destroy(sec_class, 0);
		goto exit;
	}
#endif
	return ret;
exit:
	mutex_destroy(&data->mutex);
	kfree(data);
	return ret;
}
void ktd2026_start_led_pattern(enum ktd2026_pattern mode)
{
	int retval;

	struct i2c_client *client;
	client = b_client;

	if (mode > POWERING)
		return;
	/* Set all LEDs Off */
	ktd2026_reset();
	if (mode == LED_OFF)
		return;

	/* Set to low power consumption mode */
	if (led_lowpower_mode == 1)
		led_dynamic_current = LED_LOW_CURRENT;
	else
		led_dynamic_current = LED_DEFAULT_CURRENT;

	switch (mode) {
	case CHARGING:
		ktd2026_leds_on(LED_R, LED_EN_ON, led_dynamic_current);
		break;

	case CHARGING_ERR:
		ktd2026_set_timerslot_control(1); /* Tslot2 */
		ktd2026_set_period(6);
		ktd2026_set_pwm_duty(PWM1, 127);
		ktd2026_set_pwm_duty(PWM2, 127);
		ktd2026_set_trise_tfall(0, 0, 0);
		ktd2026_leds_on(LED_R, LED_EN_PWM2, led_dynamic_current);
		break;

	case MISSED_NOTI:
		ktd2026_set_timerslot_control(1); /* Tslot2 */
		ktd2026_set_period(41);
		ktd2026_set_pwm_duty(PWM1, 232);
		ktd2026_set_pwm_duty(PWM2, 23);
		ktd2026_set_trise_tfall(0, 0, 0);
		ktd2026_leds_on(LED_B, LED_EN_PWM2, led_dynamic_current);
		break;

	case LOW_BATTERY:
		ktd2026_set_timerslot_control(1); /* Tslot2 */
		ktd2026_set_period(41);
		ktd2026_set_pwm_duty(PWM1, 232);
		ktd2026_set_pwm_duty(PWM2, 23);
		ktd2026_set_trise_tfall(0, 0, 0);
		ktd2026_leds_on(LED_R, LED_EN_PWM2, led_dynamic_current);
		break;

	case FULLY_CHARGED:
		ktd2026_leds_on(LED_G, LED_EN_ON, led_dynamic_current);
		break;

	case POWERING:
		ktd2026_set_timerslot_control(0); /* Tslot1 */
		ktd2026_set_period(14);
		ktd2026_set_pwm_duty(PWM1, 128);
		ktd2026_set_trise_tfall(7, 7, 0);
		ktd2026_leds_on(LED_B, LED_EN_ON, led_dynamic_current/2);
		ktd2026_leds_on(LED_G, LED_EN_PWM1, led_dynamic_current/3);
		break;

	default:
		return;
		break;
	}
	retval = leds_i2c_write_all(client);
	if (retval)
		pr_err("%s:leds_i2c_write_all failed\n", __func__);
}
static void an30259a_start_led_pattern(int mode)
{
	int retval;
	u8 led_r_brightness;
	u8 led_g_brightness;
	u8 led_b_brightness;
	struct i2c_client *client;
	struct work_struct *reset = 0;
	unsigned int delay_on_time = 500;
	unsigned int delay_off_time = 2000;
	client = b_client;
	
	if (mode > POWERING)
		return;
	/* Set all LEDs Off */
	an30259a_reset_register_work(reset);
	if (mode == LED_OFF)
		return;

	/* Set to low power consumption mode */
	if (LED_LOWPOWER_MODE == 1)
		LED_DYNAMIC_CURRENT = 0x9;
	else if (led_enable_fade)
		LED_DYNAMIC_CURRENT = 0x1;
	else
		LED_DYNAMIC_CURRENT = 0x48;

	if (led_intensity == 0) {	// then use stock values
		led_r_brightness = LED_R_CURRENT;
		led_g_brightness = LED_G_CURRENT;
		led_b_brightness = LED_B_CURRENT;
	}
	else {	// otherwise brightness adapts to led_intensity
		led_r_brightness = led_intensity / LED_DYNAMIC_CURRENT;
		led_g_brightness = led_intensity / LED_DYNAMIC_CURRENT;
		led_b_brightness = led_intensity / LED_DYNAMIC_CURRENT;
	}

	switch (mode) {
	/* leds_set_slope_mode(client, LED_SEL, DELAY,  MAX, MID, MIN,
		SLPTT1, SLPTT2, DT1, DT2, DT3, DT4) */
	case CHARGING:
		pr_info("LED Battery Charging Pattern on\n");
		if (led_enable_fade_charging == 1) {
			if (led_time_on)
				delay_on_time = led_time_on;
			if (led_time_off)
				delay_off_time = led_time_off;
			leds_on(LED_R, true, true,
						led_r_brightness);
			leds_set_slope_mode(client, LED_R, 0, 30, 15, 0,
				(delay_on_time + AN30259A_TIME_UNIT - 1) /
				AN30259A_TIME_UNIT,
				(delay_off_time + AN30259A_TIME_UNIT - 1) /
				AN30259A_TIME_UNIT,
				led_step_speed1, led_step_speed2, led_step_speed3, led_step_speed4);
		}
		else
			leds_on(LED_R, true, false, led_r_brightness);
		break;

	case CHARGING_ERR:
		pr_info("LED Battery Charging error Pattern on\n");
		leds_on(LED_R, true, true,
					led_r_brightness);
		leds_set_slope_mode(client, LED_R,
				1, 15, 15, 0, 1, 1, 0, 0, 0, 0);
		break;

	case MISSED_NOTI:
		pr_info("LED Missed Notifications Pattern on\n");
		leds_on(LED_B, true, true,
					led_b_brightness);
		leds_set_slope_mode(client, LED_B,
					10, 15, 15, 0, 1, 10, 0, 0, 0, 0);
		break;

	case LOW_BATTERY:
		pr_info("LED Low Battery Pattern on\n");
		leds_on(LED_R, true, true,
					led_r_brightness);
		leds_set_slope_mode(client, LED_R,
					10, 15, 15, 0, 1, 10, 0, 0, 0, 0);
		break;

	case FULLY_CHARGED:
		pr_info("LED full Charged battery Pattern on\n");
		leds_on(LED_G, true, false,
					led_g_brightness);
		break;

	case POWERING:
		pr_info("LED Powering Pattern on\n");
		leds_on(LED_G, true, true, LED_G_CURRENT);
		leds_on(LED_B, true, true, LED_B_CURRENT);
		leds_set_slope_mode(client, LED_G,
				0, 8, 4, 1, 2, 2, 3, 3, 3, 3);
		leds_set_slope_mode(client, LED_B,
				0, 15, 14, 12, 2, 2, 7, 7, 7, 7);
		break;

	default:
		return;
		break;
	}
	retval = leds_i2c_write_all(client);
	if (retval)
		printk(KERN_WARNING "leds_i2c_write_all failed\n");
}
Beispiel #13
0
static void an30259a_start_led_pattern(int mode)
{
	int retval;
	u8 r_brightness;          /* Yank555.lu : Control LED intensity (normal, bright) */
	u8 g_brightness;
	u8 b_brightness;
	struct i2c_client *client;
	struct work_struct *reset = 0;
	client = b_client;

	if (mode > POWERING)
		return;
	/* Set all LEDs Off */
	an30259a_reset_register_work(reset);
	if (mode == LED_OFF)
		return;

	/* Set to low power consumption mode */
	if (LED_LOWPOWER_MODE == 1)
		LED_DYNAMIC_CURRENT = 0x8;
	else
		LED_DYNAMIC_CURRENT = 0x1;

	/* Yank555.lu : Control LED intensity (normal, bright) */
	if (led_intensity == 0) {
		r_brightness = LED_R_CURRENT; /* CM stock behaviour */
		g_brightness = LED_G_CURRENT;
		b_brightness = LED_B_CURRENT;
	} else {
		r_brightness = led_intensity / LED_DYNAMIC_CURRENT;
		g_brightness = led_intensity / LED_DYNAMIC_CURRENT;
		b_brightness = led_intensity / LED_DYNAMIC_CURRENT;
	}

	switch (mode) {
	/* leds_set_slope_mode(client, LED_SEL, DELAY,  MAX, MID, MIN,
		SLPTT1, SLPTT2, DT1, DT2, DT3, DT4) */
	case CHARGING:
		leds_on(LED_R, true, false, r_brightness);
		break;

	case CHARGING_ERR:
		leds_on(LED_R, true, true, r_brightness);
		/* Yank555.lu : Handle fading / blinking */
		if (led_enable_fade == 1) {
			leds_set_slope_mode(client, LED_R,
					1, (15 / led_speed),  (7 / led_speed), 0, 1, 1, led_slope_up_1, led_slope_up_2, led_slope_down_1, led_slope_down_2);
		} else {
			leds_set_slope_mode(client, LED_R,
					1, (15 / led_speed), (15 / led_speed), 0, 1, 1, 0, 0, 0, 0);
		}
		break;

	case MISSED_NOTI:
		leds_on(LED_B, true, true, b_brightness);
		/* Yank555.lu : Handle fading / blinking */
		if (led_enable_fade == 1) {
			leds_set_slope_mode(client, LED_B,
						10, (15 / led_speed),  (7 / led_speed), 0, 1, (10 / led_speed), led_slope_up_1, led_slope_up_2, led_slope_down_1, led_slope_down_2);
		} else {
			leds_set_slope_mode(client, LED_B,
						10, (15 / led_speed), (15 / led_speed), 0, 1, (10 / led_speed), 0, 0, 0, 0);
		}
		break;

	case LOW_BATTERY:
		leds_on(LED_R, true, true, r_brightness);
		/* Yank555.lu : Handle fading / blinking */
		if (led_enable_fade == 1) {
			leds_set_slope_mode(client, LED_R,
						10, (15 / led_speed),  (7 / led_speed), 0, 1, (10 / led_speed), led_slope_up_1, led_slope_up_2, led_slope_down_1, led_slope_down_2);
		} else {
			leds_set_slope_mode(client, LED_R,
						10, (15 / led_speed), (15 / led_speed), 0, 1, (10 / led_speed), 0, 0, 0, 0);
		}
		break;

	case FULLY_CHARGED:
		leds_on(LED_G, true, false, g_brightness);
		break;

	case POWERING:
		leds_on(LED_G, true, true, LED_G_CURRENT);
		leds_on(LED_B, true, true, LED_B_CURRENT);
		leds_set_slope_mode(client, LED_G,
				0, 8, 4, 1, 2, 2, 3, 3, 3, 3);
		leds_set_slope_mode(client, LED_B,
				0, 15, 14, 12, 2, 2, 7, 7, 7, 7);
		break;

	default:
		return;
		break;
	}
	retval = leds_i2c_write_all(client);
	if (retval)
		printk(KERN_WARNING "leds_i2c_write_all failed\n");
}
static int __devinit ktd2026_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct ktd2026_data *data;
	int ret, i;

	pr_info("%s\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "need I2C_FUNC_I2C.\n");
		return -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
		dev_err(&client->dev, "need I2C_FUNC_SMBUS_BYTE_DATA.\n");
		return -EIO;
	}

	if (client->dev.of_node) {
		data = kzalloc(sizeof(*data), GFP_KERNEL);
		if (!data) {
			dev_err(&client->adapter->dev,
					"failed to allocate driver data.\n");
			return -ENOMEM;
		}
	} else
		data = client->dev.platform_data;

	i2c_set_clientdata(client, data);
	data->client = client;
	b_client = client;

	mutex_init(&data->mutex);

	/* initialize LED */
	/* turn off all leds */
	ktd2026_leds_on(LED_R, LED_EN_OFF, 0);
#if defined(CONFIG_SEC_FACTORY)
#if defined (CONFIG_SEC_ATLANTIC_PROJECT)
	if(batt_id_value == 0)
		ret = 1;
	else
		ret = 0;
#if defined(CONFIG_FB_MSM8x26_MDSS_CHECK_LCD_CONNECTION)
	if(get_lcd_attached() == 0)     // When LCD Not connected turning RED LED on
		ret++;;
#endif

	if(jig_power_on_value == 0)
		ret++;
	if(ret == 3)	// case when LCD not connected,battery power on and jig off
		ktd2026_leds_on(LED_R, LED_EN_ON, 30);
#endif		//ATLANTIC FLAG
#endif
	ktd2026_leds_on(LED_G, LED_EN_OFF, 0);
	ktd2026_leds_on(LED_B, LED_EN_OFF, 0);

	ktd2026_set_timerslot_control(0); /* Tslot1 */
	ktd2026_set_period(0);
	ktd2026_set_pwm_duty(PWM1, 0);
	ktd2026_set_pwm_duty(PWM2, 0);
	ktd2026_set_trise_tfall(0, 0, 0);

	for (i = 0; i < MAX_NUM_LEDS; i++) {

		ret = initialize_channel(client, &data->leds[i], i);

		if (ret < 0) {
			dev_err(&client->adapter->dev, "failure on initialization\n");
			goto exit;
		}
		INIT_WORK(&(data->leds[i].brightness_work),
				 ktd2026_led_brightness_work);
	}

	leds_i2c_write_all(client);

#ifdef SEC_LED_SPECIFIC
	led_dev = device_create(sec_class, NULL, 0, data, "led");
	if (IS_ERR(led_dev)) {
		dev_err(&client->dev,
			"Failed to create device for samsung specific led\n");
		ret = -ENODEV;
		goto exit;
	}
	ret = sysfs_create_group(&led_dev->kobj, &sec_led_attr_group);
	if (ret) {
		dev_err(&client->dev,
			"Failed to create sysfs group for samsung specific led\n");
		goto exit;
	}
#endif
	return ret;
exit:
	mutex_destroy(&data->mutex);
	kfree(data);
	return ret;
}
Beispiel #15
0
static void an30259a_start_led_pattern(int mode)
{
	int retval;

	struct i2c_client *client;
	struct work_struct *reset = 0;
	client = b_client;

	if (mode > POWERING)
		return;
	/* Set all LEDs Off */
	an30259a_reset_register_work(reset);
	if (mode == LED_OFF)
		return;

	switch (mode) {
	/* leds_set_slope_mode(client, LED_SEL, DELAY,  MAX, MID, MIN,
		SLPTT1, SLPTT2, DT1, DT2, DT3, DT4) */
	case CHARGING:
		leds_on(LED_R, true, false, LED_R_CURRENT);
		leds_on(LED_G, false, false, LED_OFF);
		leds_on(LED_B, false, false, LED_OFF);
		break;

	case CHARGING_ERR:
		leds_on(LED_R, true, true, LED_R_CURRENT);
		leds_on(LED_G, false, false, LED_OFF);
		leds_on(LED_B, false, false, LED_OFF);
		leds_set_slope_mode(client, LED_R,
				1, 15, 15, 0, 1, 1, 0, 0, 0, 0);
		break;

	case MISSED_NOTI:
		leds_on(LED_R, false, false, LED_OFF);
		leds_on(LED_G, false, false, LED_OFF);
		leds_on(LED_B, true, true, LED_B_CURRENT);
		leds_set_slope_mode(client, LED_B,
					10, 15, 15, 0, 1, 10, 0, 0, 0, 0);
		break;

	case LOW_BATTERY:
		leds_on(LED_R, true, true, LED_R_CURRENT);
		leds_on(LED_G, false, false, LED_OFF);
		leds_on(LED_B, false, false, LED_OFF);
		leds_set_slope_mode(client, LED_R,
					10, 15, 15, 0, 1, 10, 0, 0, 0, 0);
		break;

	case FULLY_CHARGED:
		leds_on(LED_R, false, false, LED_OFF);
		leds_on(LED_G, true, false, LED_G_CURRENT);
		leds_on(LED_B, false, false, LED_OFF);
		break;

	case POWERING:
		leds_on(LED_R, false, false, 0);
		leds_on(LED_G, true, true, LED_G_CURRENT);
		leds_on(LED_B, true, true, LED_B_CURRENT);
		leds_set_slope_mode(client, LED_G,
				0, 8, 4, 1, 2, 2, 3, 3, 3, 3);
		leds_set_slope_mode(client, LED_B,
				0, 15, 14, 12, 2, 2, 7, 7, 7, 7);
		break;

	default:
		return;
		break;
	}
	retval = leds_i2c_write_all(client);
	if (retval)
		printk(KERN_WARNING "leds_i2c_write_all failed\n");
}
static int __devinit an30259a_probe(struct i2c_client *client,
	const struct i2c_device_id *id)
{
	struct an30259a_data *data;
	int ret, i;

	dev_err(&client->adapter->dev, "%s\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		dev_err(&client->dev, "need I2C_FUNC_I2C.\n");
		return -ENODEV;
	}
 
	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (!data) {
		dev_err(&client->adapter->dev,
			"failed to allocate driver data.\n");
		return -ENOMEM;
	}
#ifdef CONFIG_OF
	ret = an30259a_parse_dt(&client->dev);
	if (ret) {
		pr_err("[%s] an30259a parse dt failed\n", __func__);
		kfree(data);
		return ret;
	}
#endif

	i2c_set_clientdata(client, data);
	data->client = client;
	b_client = client;

	mutex_init(&data->mutex);
	/* initialize LED */

	LED_R_CURRENT = LED_G_CURRENT = LED_B_CURRENT = led_default_cur;
	led_conf[0].max_brightness = LED_R_CURRENT;
	led_conf[1].max_brightness = LED_G_CURRENT;
	led_conf[2].max_brightness = LED_B_CURRENT;

	for (i = 0; i < MAX_NUM_LEDS; i++) {

		ret = an30259a_initialize(client, &data->leds[i], i);

		if (ret < 0) {
			dev_err(&client->adapter->dev, "failure on initialization\n");
			goto exit;
		}
		INIT_WORK(&(data->leds[i].brightness_work),
				 an30259a_led_brightness_work);
	}

#if defined (CONFIG_SEC_FACTORY)
#if defined (CONFIG_SEC_S_PROJECT)
	if ( (f_jig_cable == 0) && (get_lcd_attached() == 0) ) {
		pr_info("%s:Factory MODE - No OCTA, Battery BOOTING\n", __func__);
		leds_on(LED_R, true, false, LED_R_CURRENT);
		leds_i2c_write_all(data->client);
	}
#endif
#endif

#ifdef SEC_LED_SPECIFIC
	led_enable_fade = 0;  /* default to stock behaviour = blink */
//	led_intensity =  0;   /* default to CM behaviour = brighter blink intensity allowed */
	led_intensity = 40;   /* default to Samsung behaviour = normal intensity */
	led_speed = 1;        /* default to stock behaviour = normal blinking/fading speed */
	led_slope_up_1 = 1;   /* default slope durations for fading */
	led_slope_up_2 = 1;
	led_slope_down_1 = 1;
	led_slope_down_2 = 1;

	led_dev = device_create(sec_class, NULL, 0, data, "led");
	if (IS_ERR(led_dev)) {
		dev_err(&client->dev,
			"Failed to create device for samsung specific led\n");
		ret = -ENODEV;
		goto exit1;
	}
	ret = sysfs_create_group(&led_dev->kobj, &sec_led_attr_group);
	if (ret) {
		dev_err(&client->dev,
			"Failed to create sysfs group for samsung specific led\n");
		goto exit;
	}
#endif
	return ret;

#ifdef SEC_LED_SPECIFIC
exit1:
   device_destroy(sec_class, 0);
#endif
exit:
	mutex_destroy(&data->mutex);
	kfree(data);
	return ret;
}