Beispiel #1
0
static void pm8xxx_led_current_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	int rc, offset;
	u8 level;

	int *pduties;

	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	cancel_delayed_work_sync(&led->fade_delayed_work);
	virtual_key_state = brightness;
	if (flag_hold_virtual_key == 1) {
		LED_INFO("%s, key control \n", __func__);
		return;
	}

	if(brightness) {
		level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;

		offset = PM8XXX_LED_OFFSET(led->id);
		led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
		led->reg |= level;
		rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);

		if (led->function_flags & LED_BRETH_FUNCTION) {
			pduties = led->duties;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
		} else {
			pwm_config(led->pwm_led, 64000, 64000);
			pwm_enable(led->pwm_led);
		}
	} else {
		if (led->function_flags & LED_BRETH_FUNCTION) {
			pduties = led->duties + led->duites_size;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
						&led->fade_delayed_work,
						msecs_to_jiffies(led->duty_time_ms*led->duites_size));
		} else {
			pwm_disable(led->pwm_led);
			level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(led->id);
			led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			led->reg |= level;
			rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);
		}
	}
}
static ssize_t pm8058_led_blink_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8058_led_data *ldata;
	int id, mode;
	int val;

/*struct timespec ts1, ts2;*/

	val = -1;
	sscanf(buf, "%u", &val);
	if (val < 0 || val > 255)
		return -EINVAL;

	led_cdev = (struct led_classdev *) dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8058_led_data, ldev);

	id = bank_to_id(ldata->bank);
	mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 :
					PM_PWM_CONF_PWM1 + (ldata->bank - 4);

	if (ldata->flags & PM8058_LED_BLINK_EN)
		pm8058_pwm_config_led(ldata->pwm_led, id, mode,
				      ldata->out_current);

	printk(KERN_INFO "%s: bank %d blink %d +\n", __func__, ldata->bank, val);

	switch (val) {
	case -1: /* stop flashing */
		pwm_disable(ldata->pwm_led);
		if (ldata->flags & PM8058_LED_BLINK_EN)
			pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0);
		break;
	case 0:
		pwm_disable(ldata->pwm_led);
		if (led_cdev->brightness) {
			pwm_config(ldata->pwm_led, 64000, 64000);
			pwm_enable(ldata->pwm_led);
		} else {
			if (ldata->flags & PM8058_LED_BLINK_EN)
				pm8058_pwm_config_led(ldata->pwm_led, id,
						      mode, 0);
		}
		break;
	case 1:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 64000, 2000000);
		pwm_enable(ldata->pwm_led);
		break;
	case 2:
		cancel_delayed_work_sync(&ldata->led_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work,
				   msecs_to_jiffies(310));
		break;
	case 3:
		cancel_delayed_work_sync(&ldata->led_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work,
				   msecs_to_jiffies(1000));
		break;
	case 4:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 1000000, 2000000);
#if 0
		pwm_conf.pwm_size = 9;
		pwm_conf.clk = PM_PWM_CLK_1KHZ;
		pwm_conf.pre_div = PM_PWM_PREDIVIDE_2;
		pwm_conf.pre_div_exp = 1;
		pwm_conf.pwm_value = 512/2;
		pwm_conf.bypass_lut = 1;
		pwm_configure(ldata->pwm_led, &pwm_conf);
#endif
		pwm_enable(ldata->pwm_led);
		break;
	default:
		printk(KERN_INFO "%s: bank %d blink %d -\n", __func__, ldata->bank, val);
		return -EINVAL;
	}

	printk(KERN_INFO "%s: bank %d blink %d -\n", __func__, ldata->bank, val);
	return count;
}
Beispiel #3
0
static void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev,
					   enum led_brightness brightness)
{
	struct pm8058_led_data *ldata;
	int *pduties;
	int id, mode;
	int lut_flag;
	int milliamps;
	int enable = 0;

	ldata = container_of(led_cdev, struct pm8058_led_data, ldev);

	pwm_disable(ldata->pwm_led);
	cancel_delayed_work_sync(&ldata->led_delayed_work);

	id = bank_to_id(ldata->bank);
	mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 :
					PM_PWM_CONF_PWM1 + (ldata->bank - 4);

	brightness = (brightness > LED_FULL) ? LED_FULL : brightness;
	brightness = (brightness < LED_OFF) ? LED_OFF : brightness;
	LED_INFO_LOG("%s: bank %d brightness %d +\n", __func__,
	       ldata->bank, brightness);

	enable = (brightness) ? 1 : 0;
	if (strcmp(ldata->ldev.name, "charming-led") == 0)
		charming_led_enable(enable);

	lut_flag = ldata->lut_flag & ~(PM_PWM_LUT_LOOP | PM_PWM_LUT_REVERSE);
	virtual_key_state = enable;
	if (flag_hold_virtual_key == 1) {
		LED_INFO_LOG("%s, Return control by button_backlight flash \n", __func__);
		return;
	}

	if (brightness) {
		milliamps = (ldata->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ?
			    ldata->out_current * brightness / LED_FULL :
			    ldata->out_current;
		pm8058_pwm_config_led(ldata->pwm_led, id, mode, milliamps);
		if (ldata->flags & PM8058_LED_LTU_EN) {
			pduties = &duty_array[ldata->start_index];
			pm8058_pwm_lut_config(ldata->pwm_led,
					      ldata->period_us,
					      pduties,
					      ldata->duty_time_ms,
					      ldata->start_index,
					      ldata->duites_size,
					      0, 0,
					      lut_flag);
			pm8058_pwm_lut_enable(ldata->pwm_led, 0);
			pm8058_pwm_lut_enable(ldata->pwm_led, 1);
		} else {
			pwm_config(ldata->pwm_led, 64000, 64000);
			pwm_enable(ldata->pwm_led);
		}
	} else {
		if (ldata->flags & PM8058_LED_LTU_EN) {
			wake_lock_timeout(&pmic_led_wake_lock,HZ*2);
			pduties = &duty_array[ldata->start_index +
					  ldata->duites_size];
			pm8058_pwm_lut_config(ldata->pwm_led,
					      ldata->period_us,
					      pduties,
					      ldata->duty_time_ms,
					      ldata->start_index +
					      ldata->duites_size,
					      ldata->duites_size,
					      0, 0,
					      lut_flag);
			pm8058_pwm_lut_enable(ldata->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
					   &ldata->led_delayed_work,
					   msecs_to_jiffies(ldata->duty_time_ms * ldata->duites_size));

			LED_INFO_LOG("%s: bank %d fade out brightness %d -\n", __func__,
			ldata->bank, brightness);
			return;
		} else
			pwm_disable(ldata->pwm_led);
		pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0);
	}
	LED_INFO_LOG("%s: bank %d brightness %d -\n", __func__, ldata->bank, brightness);
}
Beispiel #4
0
static void handle_twi_command(void)
{
    uint8_t command;

    // Get the command from the receive buffer.
    command = twi_receive_byte();

    switch (command)
    {
    case TWI_CMD_RESET:

        // Reset the servo.
        watchdog_hard_reset();

        break;

    case TWI_CMD_PWM_ENABLE:

        // Enable PWM to the servo motor.
        pwm_enable();

        break;

    case TWI_CMD_PWM_DISABLE:

        // Disable PWM to the servo motor.
        pwm_disable();

        break;

    case TWI_CMD_WRITE_ENABLE:

        // Enable write to read/write protected registers.
        registers_write_enable();

        break;

    case TWI_CMD_WRITE_DISABLE:

        // Disable write to read/write protected registers.
        registers_write_disable();

        break;

    case TWI_CMD_REGISTERS_SAVE:

        // Save register values into EEPROM.
        eeprom_save_registers();

        break;

    case TWI_CMD_REGISTERS_RESTORE:

        // Restore register values into EEPROM.
        eeprom_restore_registers();

        break;

    case TWI_CMD_REGISTERS_DEFAULT:

        // Restore register values to factory defaults.
        registers_defaults();
        break;

    case TWI_CMD_EEPROM_ERASE:

        // Erase the EEPROM.
        eeprom_erase();

        break;

    case TWI_CMD_VOLTAGE_READ:

        // Request a voltage reading.
        adc_read_voltage();

        break;

#if CURVE_MOTION_ENABLED
    case TWI_CMD_CURVE_MOTION_ENABLE:

        // Enable curve motion handling.
        motion_enable();

        break;

    case TWI_CMD_CURVE_MOTION_DISABLE:

        // Disable curve motion handling.
        motion_disable();

        break;

    case TWI_CMD_CURVE_MOTION_RESET:

        // Reset the motion to the current position.
#if ENCODER_ENABLED
        motion_reset(enc_get_position_value());
#else
        motion_reset(adc_get_position_value());
#endif

        break;

    case TWI_CMD_CURVE_MOTION_APPEND:

        // Append motion curve data stored in the registers.
        motion_append();

        break;
#endif

    default:

        // Ignore unknown command.
        break;
    }
}
void max77833_vibtonz_en(bool en)
{
	int error = 0, temperature_level;
	if (g_hap_data == NULL) {
		pr_err("[VIB] the motor is not ready!!!");
		return ;
	}

	if (en) {
		if (g_hap_data->running)
			return;
		max77833_haptic_i2c(g_hap_data, true);
		temperature_level = temperature_check();

		if (temperature_level != prev_temperature_level) {
			switch(temperature_level)
			{
				case 0:
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_MIN_FREQ_LOW, g_hap_data->pdata->auto_res_min_low_low_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
					}
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_MAX_FREQ_LOW, g_hap_data->pdata->auto_res_max_low_low_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
					}
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_INIT_GUESS_LOW, g_hap_data->pdata->auto_res_init_low_low_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
					}
					break;
				case 1:
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_MIN_FREQ_LOW, g_hap_data->pdata->auto_res_min_low);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
					}
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_MAX_FREQ_LOW, g_hap_data->pdata->auto_res_max_low);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
					}
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_INIT_GUESS_LOW, g_hap_data->pdata->auto_res_init_low);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
					}
					break;
				case 2:
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_MIN_FREQ_LOW, g_hap_data->pdata->auto_res_min_low_high_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
					}
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_MAX_FREQ_LOW, g_hap_data->pdata->auto_res_max_low_high_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
					}
					error = max77833_write_reg(g_hap_data->i2c,
						MAX77833_AUTORES_INIT_GUESS_LOW, g_hap_data->pdata->auto_res_init_low_high_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
					}
					break;
				default:
					pr_err("[VIB] %s Failed to read temperature [%d]\n",
					__func__, temperature_level);
					break;
			}
		}
		prev_temperature_level = temperature_level;

		pwm_config(g_hap_data->pwm, prev_duty, g_hap_data->pdata->period);
		pwm_enable(g_hap_data->pwm);

		g_hap_data->running = true;

	} else {
		if (!g_hap_data->running)
			return;
		pwm_disable(g_hap_data->pwm);
		max77833_haptic_i2c(g_hap_data, false);
		g_hap_data->running = false;
	}
}
static void pm8xxx_led_current_set_flagged(struct led_classdev *led_cdev, enum led_brightness brightness, int blink)
{
	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	int rc, offset;
	u8 level;

	int *pduties;

	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	cancel_delayed_work_sync(&led->fade_delayed_work);
	virtual_key_state = brightness;
	if (flag_hold_virtual_key == 1) {
		LED_INFO("%s, key control \n", __func__);
		return;
	}

	if(brightness) {
		level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
		offset = PM8XXX_LED_OFFSET(led->id);
		led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
		led->reg |= level;
		rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);

		if (led->function_flags & LED_BRETH_FUNCTION) {
			if (blink == 0) {
				buttons_led_is_on = 1;
				// no blink needed
				pduties = &dutys_array[0];
				pm8xxx_pwm_lut_config(led->pwm_led,
							led->period_us,
							pduties,
							led->duty_time_ms,
							led->start_index,
							led->duites_size,
							0, 0,
							led->lut_flag);
			} else {
				pduties = &dutys_array[0];
				// LUT_LOOP for blinking
				pm8xxx_pwm_lut_config(led->pwm_led,
							led->period_us,
							pduties,
							led->duty_time_ms, // slower, 2x
							led->start_index,
							led->duites_size * 8, // 16 duty entries -> original size * 2, + 6 * 8 zeroes for pause
							0, 0,
							PM_PWM_LUT_LOOP | PM_PWM_LUT_PAUSE_HI_EN);
			}
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
		} else {
			pwm_config(led->pwm_led, 6400 * led->pwm_coefficient / 100, 6400);
			pwm_enable(led->pwm_led);
		}
	} else {
		if (led->function_flags & LED_BRETH_FUNCTION) {
			buttons_led_is_on = 0;
			wake_lock_timeout(&pmic_led_wake_lock, HZ*2);
			pduties = &dutys_array[8];
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
						&led->fade_delayed_work,
						msecs_to_jiffies(led->duty_time_ms*led->duites_size));
		} else {
			pwm_disable(led->pwm_led);
			level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(led->id);
			led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			led->reg |= level;
			rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);
		}
	}
}
static ssize_t pm8xxx_led_blink_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;
	int val;
	int level, offset;
	int led_is_green;

	val = -1;
	sscanf(buf, "%u", &val);
	if (val < 0 || val > 255)
		return -EINVAL;
	current_blink= val;
	led_cdev = (struct led_classdev *) dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("%s: bank %d blink %d sync %d\n", __func__, ldata->bank, val, ldata->led_sync);
	printk("%s: [BB] bank %d blink %d sync %d\n", __func__, ldata->bank, val, ldata->led_sync);
	if (!strcmp(ldata->cdev.name, "green")) {
		led_is_green = 1;
	}
	if (!strcmp(ldata->cdev.name, "amber")) {
		led_is_green = 0;
	}

	switch (val) {
	case BLINK_STOP:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(0);
		pwm_disable(ldata->pwm_led);

		if(ldata->led_sync) {
			if 	(!strcmp(ldata->cdev.name, "green")) {
				if (green_back_led_data->gpio_status_switch != NULL)
					green_back_led_data->gpio_status_switch(0);
				pwm_disable(green_back_led_data->pwm_led);
			}
			if 	(!strcmp(ldata->cdev.name, "amber")) {
				if (amber_back_led_data->gpio_status_switch != NULL)
					amber_back_led_data->gpio_status_switch(0);
				pwm_disable(amber_back_led_data->pwm_led);
			}
		}
		if (blink_buttons > 0) {
			if (led_is_green == 1) {
				green_blink_value = 0;
			} else {
				amber_blink_value = 0;
			}
			pm8xxx_buttons_blink(0);
		}
		break;
	case BLINK_UNCHANGE:
		pwm_disable(ldata->pwm_led);
		if (led_cdev->brightness) {
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(1);
			pwm_config(ldata->pwm_led, 6400 * ldata->pwm_coefficient / 100, 6400);
			pwm_enable(ldata->pwm_led);

			if(ldata->led_sync) {
				if	(!strcmp(ldata->cdev.name, "green")) {
					if (green_back_led_data->gpio_status_switch != NULL)
						green_back_led_data->gpio_status_switch(1);
					pwm_config(green_back_led_data->pwm_led, 64000, 64000);
					pwm_enable(green_back_led_data->pwm_led);
				}
				if	(!strcmp(ldata->cdev.name, "amber")) {
					if (amber_back_led_data->gpio_status_switch != NULL)
						amber_back_led_data->gpio_status_switch(1);
					pwm_config(amber_back_led_data->pwm_led, 64000, 64000);
					pwm_enable(amber_back_led_data->pwm_led);
				}
			}
			if (blink_buttons > 0 && val > 0) {
				if (led_is_green == 1) {
					green_blink_value = 1;
				} else {
					amber_blink_value = 1;
				}
				pm8xxx_buttons_blink(1);
			}
		} else {
			pwm_disable(ldata->pwm_led);
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(0);

			if(ldata->led_sync) {
				if (!strcmp(ldata->cdev.name, "green")){
					if (green_back_led_data->gpio_status_switch != NULL)
						green_back_led_data->gpio_status_switch(0);
					pwm_disable(green_back_led_data->pwm_led);
					level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
					offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
					green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
					green_back_led_data->reg |= level;
					pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
				}
				if (!strcmp(ldata->cdev.name, "amber")){
					if (amber_back_led_data->gpio_status_switch != NULL)
						amber_back_led_data->gpio_status_switch(0);
					pwm_disable(amber_back_led_data->pwm_led);
					level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
					offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
					amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
					amber_back_led_data->reg |= level;
					pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
				}
			}
			if (blink_buttons > 0) {
				if (led_is_green == 1) {
					green_blink_value = 0;
				} else {
					amber_blink_value = 0;
				}
				pm8xxx_buttons_blink(0);
			}
		}
		break;
	case BLINK_64MS_PER_2SEC:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(1);
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, ldata->blink_duty_per_2sec, 2000000);
		pwm_enable(ldata->pwm_led);

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				if (green_back_led_data->gpio_status_switch != NULL)
					green_back_led_data->gpio_status_switch(1);
				pwm_disable(green_back_led_data->pwm_led);
				pwm_config(green_back_led_data->pwm_led, ldata->blink_duty_per_2sec, 2000000);
				pwm_enable(green_back_led_data->pwm_led);
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				if (amber_back_led_data->gpio_status_switch != NULL)
					amber_back_led_data->gpio_status_switch(1);
				pwm_disable(amber_back_led_data->pwm_led);
				pwm_config(amber_back_led_data->pwm_led, ldata->blink_duty_per_2sec, 2000000);
				pwm_enable(amber_back_led_data->pwm_led);
			}
		}
		if (blink_buttons > 0 && val > 0) {
			if (led_is_green == 1) {
				green_blink_value = 1;
			} else {
				amber_blink_value = 1;
			}
			pm8xxx_buttons_blink(1);
		}
		break;
	case BLINK_64MS_ON_310MS_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				pwm_disable(green_back_led_data->pwm_led);
				green_back_led_data->duty_time_ms = 64;
				green_back_led_data->period_us = 2000000;
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				pwm_disable(amber_back_led_data->pwm_led);
				amber_back_led_data->duty_time_ms = 64;
				amber_back_led_data->period_us = 2000000;
			}
		}
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(310));
		break;
	case BLINK_64MS_ON_2SEC_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				pwm_disable(green_back_led_data->pwm_led);
				green_back_led_data->duty_time_ms = 64;
				green_back_led_data->period_us = 2000000;
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				pwm_disable(amber_back_led_data->pwm_led);
				amber_back_led_data->duty_time_ms = 64;
				amber_back_led_data->period_us = 2000000;
			}
		}
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(1000));
		break;
	case BLINK_1SEC_PER_2SEC:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 1000000, 2000000);
		pwm_enable(ldata->pwm_led);

		if(ldata->led_sync) {
			if	(!strcmp(ldata->cdev.name, "green")) {
				pwm_disable(green_back_led_data->pwm_led);
				pwm_config(green_back_led_data->pwm_led, 1000000, 2000000);
				pwm_enable(green_back_led_data->pwm_led);
			}
			if	(!strcmp(ldata->cdev.name, "amber")) {
				pwm_disable(amber_back_led_data->pwm_led);
				pwm_config(amber_back_led_data->pwm_led, 1000000, 2000000);
				pwm_enable(amber_back_led_data->pwm_led);
			}
		}
		break;
	default:
		LED_ERR("%s: bank %d did not support blink type %d\n", __func__, ldata->bank, val);
		return -EINVAL;
	}

	return count;
}
static int pwm_test_probe(struct platform_device *pdev)
{
	struct pwm_test *pwm_test;
	struct pinctrl *pinctrl;
	struct device_node *node = (&pdev->dev)->of_node;
	int rc;

	pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(pinctrl))
		dev_warn(&pdev->dev, "unable to select pin group. PWM not muxed right\n");


	pwm_test = devm_kzalloc(&pdev->dev, sizeof(*pwm_test), GFP_KERNEL);

	if (!pwm_test) {
		dev_err(&pdev->dev, "memory error\n");
		return -ENOMEM;
	}

	if (pwm_test_class_init(&pdev->dev)) {
		dev_err(&pdev->dev, "sysfs creation failed\n");
		return -EINVAL;
	}

	pwm_test->pwm = devm_pwm_get(&pdev->dev, NULL);
	if (IS_ERR(pwm_test->pwm)) {
		dev_err(&pdev->dev, "unable to request PWM\n");	
		return -EINVAL;			
	}

	pwm_test->requested = 1;

	pr_debug("pwm_test got PWM\n");

	/* Get the properties of the pwm. This is set in the device driver (tiehrpwm) */
	pwm_test->period = pwm_get_period(pwm_test->pwm);

	/* Determine running or not from the device tree */
	rc = of_property_read_u32(node, "enabled", (u32*) &(pwm_test->run));
	if (rc < 0)
		return rc;

	if(pwm_test->run){
		rc = pwm_enable(pwm_test->pwm);
		if (rc < 0)
				return rc;
	}

	/* Determine the duty from the device tree */
	rc = of_property_read_u32(node, "duty", (u32*) &(pwm_test->duty_s));
	if (rc < 0)
		return rc;

	rc = pwm_config(pwm_test->pwm, pwm_test->duty_s, pwm_test->period);
	if (rc) {
		pr_err("Unable to set pwm duty %d\n", rc);
		return rc;
	}
	

	platform_set_drvdata(pdev, pwm_test);
	return 0;
}
int backlight_pwm_gpio_config(void)
{
    int rc;
	struct pm_gpio backlight_drv = 
	{
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 0,
		.pull           = PM_GPIO_PULL_NO,
		.vin_sel        = 0,
		.out_strength   = PM_GPIO_STRENGTH_HIGH,
		.function       = PM_GPIO_FUNC_2,
		.inv_int_pol 	= 1,
	};
	/* U8800 use PM_GPIO25 as backlight's PWM,but U8820 use PM_GPIO26 */
    if(machine_is_msm7x30_u8800() 
		|| machine_is_msm7x30_u8800_51() 
		|| machine_is_msm8255_u8800_pro() 
		|| machine_is_msm8255_u8860() 
		|| machine_is_msm8255_c8860() 
		|| machine_is_msm8255_u8860lp()
        || machine_is_msm8255_u8860_r()
		|| machine_is_msm8255_u8860_92()
		|| machine_is_msm8255_u8680()
		|| machine_is_msm8255_u8667()
		|| machine_is_msm8255_u8860_51()
		|| machine_is_msm8255_u8730())
	{
        rc = pm8xxx_gpio_config( 24, &backlight_drv);
    }
    else if(machine_is_msm7x30_u8820()) 
    {
    	rc = pm8xxx_gpio_config( 25, &backlight_drv);
    }
	else
	{
    	rc = -1;
	}
	
    if (rc) 
	{
		pr_err("%s LCD backlight GPIO config failed\n", __func__);
		return rc;
	}
    return 0;
}
/* use the mmp pin like three-leds */
void msm_backlight_set(int level)
{
    static uint8 last_level = 0;
/*fix bug in new base-line 1025*/
#ifdef CONFIG_ARCH_MSM7X30
	static boolean first_set_bl = TRUE;
	static struct pwm_device *bl_pwm;
#endif	//CONFIG_ARCH_MSM7X30
	/* keep duty 10% < level < 100% */
#ifdef CONFIG_ARCH_MSM7X27A
	if(level)
	{
		if (level < BL_MIN_LEVEL)        
		{    
			level = BL_MIN_LEVEL;      
		}
	}
    if (last_level == level)
    {
        return ;
    }
    last_level = level;
	pmapp_disp_backlight_set_brightness(last_level);
#endif

#ifdef CONFIG_ARCH_MSM7X30
	if(TRUE == first_set_bl)
	{
		backlight_pwm_gpio_config();
		/* U8800 use PM_GPIO25 as backlight's PWM,but U8820 use PM_GPIO26 */
		if(machine_is_msm7x30_u8800() 
			|| machine_is_msm7x30_u8800_51() 
			|| machine_is_msm8255_u8800_pro()
			|| machine_is_msm8255_u8860() 
			|| machine_is_msm8255_c8860()
			|| machine_is_msm8255_u8860lp()
            || machine_is_msm8255_u8860_r()
			|| machine_is_msm8255_u8860_92()
			|| machine_is_msm8255_u8680()
			|| machine_is_msm8255_u8667()
			|| machine_is_msm8255_u8860_51()
			|| machine_is_msm8255_u8730())

		{
			bl_pwm = pwm_request(PM_GPIO25_PWM_ID, "backlight");
		}
		else if(machine_is_msm7x30_u8820())
		{
			bl_pwm = pwm_request(PM_GPIO26_PWM_ID, "backlight");
		}
		else
		{
			bl_pwm = NULL;
		}

		if (NULL == bl_pwm || IS_ERR(bl_pwm)) 
		{
			pr_err("%s: pwm_request() failed\n", __func__);
			bl_pwm = NULL;
		}
		first_set_bl = FALSE;
	}
	if (bl_pwm)
	{
		if(level)
		{
			level = ((level * PWM_LEVEL_ADJUST) / PWM_LEVEL + ADD_VALUE); 
			if (level < BL_MIN_LEVEL)
			{
				level = BL_MIN_LEVEL;
			}
		}	
	    if (last_level == level)
	    {
	        return ;
	    }
	    last_level = level;
		pwm_config(bl_pwm, PWM_DUTY_LEVEL*level/NSEC_PER_USEC, PWM_PERIOD/NSEC_PER_USEC);
		pwm_enable(bl_pwm);
	}
#endif
}

void cabc_backlight_set(struct msm_fb_data_type * mfd)
{	     
	struct msm_fb_panel_data *pdata = NULL;   
	uint32 bl_level = mfd->bl_level;
		/* keep duty 10% < level < 100% */
	if (bl_level)    
   	{   
	/****delete one line codes for backlight*****/
		if (bl_level < BL_MIN_LEVEL)        
		{    
			bl_level = BL_MIN_LEVEL;      
		}  
	}
	/* backlight ctrl by LCD-self, like as CABC */  
	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;  
	if ((pdata) && (pdata->set_cabc_brightness))   
   	{       
		pdata->set_cabc_brightness(mfd,bl_level);
	}

}

void pwm_set_backlight(struct msm_fb_data_type *mfd)
{
	/*< Delete unused variable */
	/*When all the device are resume that can turn the light*/
	if(atomic_read(&suspend_flag)) 
	{
		mfd_local = mfd;
		backlight_set = TRUE;
		return;
	}
	/*< Delete some lines,control backlight in hardware lights.c by property */
	if (get_hw_lcd_ctrl_bl_type() == CTRL_BL_BY_MSM)
	{
		msm_backlight_set(mfd->bl_level);
 	}   
	else    
 	{
		cabc_backlight_set(mfd);  
 	}
	return;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void pwm_backlight_suspend( struct early_suspend *h)
{
	atomic_set(&suspend_flag,1);
}
Beispiel #10
0
/**
 ****************************************************************************************
 * @brief   Switch buzzer off
 ****************************************************************************************
 */
void buzzer_off(void)
{
    pwm_enable(PWM_CH1, MASK_DISABLE);
}
int backlight_pwm_gpio_config(void)
{
    int rc;
	struct pm_gpio backlight_drv = 
	{
		.direction      = PM_GPIO_DIR_OUT,
		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
		.output_value   = 0,
		.pull           = PM_GPIO_PULL_NO,
		.vin_sel        = 0,
		.out_strength   = PM_GPIO_STRENGTH_HIGH,
		.function       = PM_GPIO_FUNC_2,
		.inv_int_pol 	= 1,
	};
	/* U8800 use PM_GPIO25 as backlight's PWM,but U8820 use PM_GPIO26 */
/* < DTS2011102401822 liwei 20111024 begin */
    if(machine_is_msm7x30_u8800() 
		|| machine_is_msm7x30_u8800_51() 
		|| machine_is_msm8255_u8800_pro() 
		|| machine_is_msm8255_u8860() 
		|| machine_is_msm8255_c8860() 
		|| machine_is_msm8255_u8860lp()
        /* < DTS2012022905490 ganfan 20120301 begin */
        || machine_is_msm8255_u8860_r()
        /* DTS2012022905490 ganfan 20120301 end > */
		|| machine_is_msm8255_u8860_92()
		|| machine_is_msm8255_u8680()
		|| machine_is_msm8255_u8667()
		|| machine_is_msm8255_u8860_51()
		|| machine_is_msm8255_u8730())
/* DTS2011102401822 liwei 20111024 end > */
    /*< DTS2012051704510 houming 20120517 begin */
    /* renew config the gpio value */
	{
        rc = pm8xxx_gpio_config( PM8058_GPIO_PM_TO_SYS(24), &backlight_drv);
    }
    else if(machine_is_msm7x30_u8820()) 
    {
    	rc = pm8xxx_gpio_config( PM8058_GPIO_PM_TO_SYS(25), &backlight_drv);
    }
	/* DTS2012051704510 houming 20120517 end >*/
	else
	{
    	rc = -1;
	}
	
    if (rc) 
	{
		pr_err("%s LCD backlight GPIO config failed\n", __func__);
		return rc;
	}
    return 0;
}
/* use the mmp pin like three-leds */
/*< DTS2012012101194 lijianzhao 20120121 begin */
void msm_backlight_set(int level)
{
    static uint8 last_level = 0;
	static boolean first_set_bl = TRUE;
	/*< DTS2012042605475 zhongjinrong 20120426 begin  */
	/*< DTS2012032101654 liweiwu 20120321 begin */
	/* keep duty 10% < level < 100% */
	/* DTS2012032101654 liweiwu 20120321 end >*/
	/* DTS2012042605475 zhongjinrong 20120426 end >*/
/*< DTS2012021602342 zhongjinrong 20120224 begin */
#ifdef CONFIG_ARCH_MSM7X27A
/* DTS2012021602342 zhongjinrong 20120224 end >*/
	if(level)
	{
		level = ((level * PWM_LEVEL_ADJUST_LPG) / PWM_LEVEL ); 
		if (level < BL_MIN_LEVEL_LPG)        
		{    
			level = BL_MIN_LEVEL_LPG;      
		}
	}
    if (last_level == level)
    {
        return ;
    }
    last_level = level;
	pmapp_disp_backlight_set_brightness(last_level);
#endif

#ifdef CONFIG_ARCH_MSM7X30
	if(TRUE == first_set_bl)
	{
		backlight_pwm_gpio_config();
		/* U8800 use PM_GPIO25 as backlight's PWM,but U8820 use PM_GPIO26 */
/* < DTS2011102401822 liwei 20111024 begin */
		if(machine_is_msm7x30_u8800() 
			|| machine_is_msm7x30_u8800_51() 
			|| machine_is_msm8255_u8800_pro()
			|| machine_is_msm8255_u8860() 
			|| machine_is_msm8255_c8860()
			|| machine_is_msm8255_u8860lp()
            /* < DTS2012022905490 ganfan 20120301 begin */
            || machine_is_msm8255_u8860_r()
            /* DTS2012022905490 ganfan 20120301 end > */
			|| machine_is_msm8255_u8860_92()
			|| machine_is_msm8255_u8680()
			|| machine_is_msm8255_u8667()
			|| machine_is_msm8255_u8860_51()
			|| machine_is_msm8255_u8730())
/* DTS2011102401822 liwei 20111024 end > */

		{
			bl_pwm = pwm_request(PM_GPIO25_PWM_ID, "backlight");
		}
		else if(machine_is_msm7x30_u8820())
		{
			bl_pwm = pwm_request(PM_GPIO26_PWM_ID, "backlight");
		}
		else
		{
			bl_pwm = NULL;
		}

		if (NULL == bl_pwm || IS_ERR(bl_pwm)) 
		{
			pr_err("%s: pwm_request() failed\n", __func__);
			bl_pwm = NULL;
		}
		first_set_bl = FALSE;
	}
	if (bl_pwm)
	{
		if(level)
		{
			level = ((level * PWM_LEVEL_ADJUST) / PWM_LEVEL + ADD_VALUE); 
			if (level < BL_MIN_LEVEL)
			{
				level = BL_MIN_LEVEL;
			}
		}	
	    if (last_level == level)
	    {
	        return ;
	    }
	    last_level = level;
		pwm_config(bl_pwm, PWM_DUTY_LEVEL*level/NSEC_PER_USEC, PWM_PERIOD/NSEC_PER_USEC);
		pwm_enable(bl_pwm);
	}
#endif
}
/* DTS2012012101194 lijianzhao 20120121 end >*/

void cabc_backlight_set(struct msm_fb_data_type * mfd)
{	     
	struct msm_fb_panel_data *pdata = NULL;   
	uint32 bl_level = mfd->bl_level;
	/*< DTS2012042605475 zhongjinrong 20120426 begin  */
	/*< DTS2012032101654 liweiwu 20120321 begin  */
		/* keep duty 10% < level < 100% */
	/* DTS2012032101654 liweiwu 20120321 end >*/
	if (bl_level)    
   	{   
   	/*< DTS2012032101654 liweiwu 20120321 begin  */
	/****delete one line codes for backlight*****/
	/* DTS2012032101654 liweiwu 20120321 end >*/
	/* DTS2012042605475 zhongjinrong 20120426 end >*/
		if (bl_level < BL_MIN_LEVEL)        
		{    
			bl_level = BL_MIN_LEVEL;      
		}  
	}
	/* backlight ctrl by LCD-self, like as CABC */  
	/*< DTS2012012101194 lijianzhao 20120121 begin */
	pdata = (struct msm_fb_panel_data *)mfd->pdev->dev.platform_data;  
	if ((pdata) && (pdata->set_cabc_brightness))   
   	{       
		pdata->set_cabc_brightness(mfd,bl_level);
	}
	/* DTS2012012101194 lijianzhao 20120121 end >*/

}

/*< DTS2012022408079 zhongjinrong 20120306 begin */
void pwm_set_backlight(struct msm_fb_data_type *mfd)
{
	lcd_panel_type lcd_panel_wvga = LCD_NONE;
	/*< DTS2011122704239 liuyuntao 20111229 begin */
	/*When all the device are resume that can turn the light*/
	if(atomic_read(&suspend_flag)) 
	{
		mfd_local = mfd;
		backlight_set = TRUE;
		return;
	}
	/* DTS2011122704239 liuyuntao 20111229 end >*/
/*< DTS2012021601331 duanfei 20120216 begin */
/*< DTS2012021602342 zhongjinrong 20120224 begin */
#ifdef CONFIG_ARCH_MSM7X27A
/* DTS2012021602342 zhongjinrong 20120224 end >*/
	
	
	lcd_panel_wvga = get_lcd_panel_type();
	/* <DTS2012022501992 liguosheng 20120229 begin */
	if ((MIPI_RSP61408_CHIMEI_WVGA == lcd_panel_wvga ) 
		|| (MIPI_RSP61408_BYD_WVGA == lcd_panel_wvga )
		|| (MIPI_RSP61408_TRULY_WVGA == lcd_panel_wvga )
		|| (MIPI_HX8369A_TIANMA_WVGA == lcd_panel_wvga ))
	{
		/* keep duty is 75% of the quondam duty */
		mfd->bl_level = mfd->bl_level * 75 / 100;
	}
	/* DTS2012022501992 liguosheng 20120229 end> */
#endif
/* DTS2012021601331 duanfei 20120216 end >*/
	if (get_hw_lcd_ctrl_bl_type() == CTRL_BL_BY_MSM)
	{
		msm_backlight_set(mfd->bl_level);
 	}   
	else    
 	{
		cabc_backlight_set(mfd);  
 	}
	return;
}
Beispiel #12
0
/**
 ****************************************************************************************
 * @brief   Switch buzzer on
 * @param[in]    volume     buzzer's volume
 ****************************************************************************************
 */
void buzzer_on(enum buzz_vol volume)
{
    pwm_init(PWM_CH1);
    pwm_config(PWM_CH1, PWM_PSCAL_DIV, PWM_COUNT_US(BUZZ_PWM_PERIOD, PWM_PSCAL_DIV), PWM_COUNT_US(volume, PWM_PSCAL_DIV));
    pwm_enable(PWM_CH1, MASK_ENABLE);
}
Beispiel #13
0
/*configure GPIO 25 Of PIMIC as PWM to driver LED*/
int led_pwm_gpio_config(void)
{
    int rc;
    struct pm_gpio backlight_drv = 
    {
        .direction      = PM_GPIO_DIR_OUT,
        .output_buffer  = PM_GPIO_OUT_BUF_CMOS,
        .output_value   = 0,
        .pull           = PM_GPIO_PULL_NO,
        .vin_sel        = 0,
        .out_strength   = PM_GPIO_STRENGTH_HIGH,
        .function       = PM_GPIO_FUNC_2,
        .inv_int_pol 	= 1,
    };
    if(machine_is_msm8255_u8860lp()
    || machine_is_msm8255_u8860_r()
	 ||machine_is_msm8255_u8860_51())
    {
        rc = pm8xxx_gpio_config( 24, &backlight_drv);
    }
    else
    {
        rc = -1;
    }
	
    if (rc) 
    {
        pr_err("%s LED backlight GPIO config failed\n", __func__);
        return rc;
    }
    return 0;
}
#endif

static void msm_keypad_bl_led_set(struct led_classdev *led_cdev,
	enum led_brightness value)
{
#ifdef CONFIG_HUAWEI_LEDS_PMIC
    int ret = 0;
/* 7x27a platform use mpp7 as keypad backlight */
	#ifdef CONFIG_ARCH_MSM7X27A
	    if(machine_is_msm7x27a_C8820())
	    {
	        ret = pmic_secure_mpp_config_i_sink(PM_MPP_7, PM_MPP__I_SINK__LEVEL_5mA, \
	            (!!value) ? PM_MPP__I_SINK__SWITCH_ENA : PM_MPP__I_SINK__SWITCH_DIS);
	    }
	    else
	    {
	        /* use pwm to control the brightness of keypad backlight*/
	        /* make sure the led is drived by pwm when */
	        /* the system sleep indicator switch is on */
	        pmapp_button_backlight_init();

	        ret = pmapp_button_backlight_set_brightness(value);
	    }
	#else
	    if(machine_is_msm7x30_u8800() || machine_is_msm7x30_u8800_51() || machine_is_msm8255_u8800_pro() ) 
	    {
	      ret = pmic_set_led_intensity(LED_KEYPAD, !( ! value));
	    }
	    else if( machine_is_msm8255_u8860lp()	
        || machine_is_msm8255_u8860_r()
		       ||machine_is_msm8255_u8860_51())
	    {
	        pwm_config(bl_pwm, LED_PWM_DUTY_LEVEL*value/NSEC_PER_USEC, LED_PWM_PERIOD/NSEC_PER_USEC);
	        pwm_enable(bl_pwm);
	    }
	    else if(machine_is_msm7x30_u8820()
		    || (machine_is_msm8255_u8730()))
	    {   
	      ret = pmic_set_mpp6_led_intensity(!( ! value));
	    }
		/*< when the value between 0 and 255,set the key brightness is LED_BRIGHRNESS_LEVEL or set the brightness is 0 */
		else if( machine_is_msm8255_u8860() 
		      || machine_is_msm8255_c8860() 
			  || machine_is_msm8255_u8860_92())
		{
	       if(LED_BRIGHTNESS_OFF >= value || LED_PWM_LEVEL < value )
	       {
		   	   ret = pmic_set_keyled_intensity(LED_KEYPAD,LED_BRIGHTNESS_OFF  );
	       }
		   else 
		   {
		   	   ret = pmic_set_keyled_intensity(LED_KEYPAD, LED_BRIGHTNESS_LEVEL);
		   }
		}
    else if(machine_is_msm8255_u8680())
    {   
	    /* Set keypad led brightness level 12 for U8680 */
        if(LED_BRIGHTNESS_OFF >= value || LED_PWM_LEVEL < value)
        {
            ret = pmic_set_keyled_intensity(LED_KEYPAD,LED_BRIGHTNESS_OFF);
        }
        else 
        {
            ret = pmic_set_keyled_intensity(LED_KEYPAD, LED_BRIGHTNESS_LEVEL_U8680);
        }	
    }
    else if(machine_is_msm8255_u8667())
    {   
        /* Set keypad led brightness level 16 for U8667 */
        if(LED_BRIGHTNESS_OFF >= value || LED_PWM_LEVEL < value)
        {
            ret = pmic_set_keyled_intensity(LED_KEYPAD, LED_BRIGHTNESS_OFF);
        }
        else 
        {
            ret = pmic_set_keyled_intensity(LED_KEYPAD, LED_BRIGHTNESS_LEVEL_U8667);
        }	
    }
	#endif
    if (ret)
		dev_err(led_cdev->dev, "can't set keypad backlight\n");
#else
	int ret;

	ret = pmic_set_led_intensity(LED_KEYPAD, value / MAX_KEYPAD_BL_LEVEL);
	if (ret)
		dev_err(led_cdev->dev, "can't set keypad backlight\n");
#endif
}
Beispiel #14
0
static ssize_t pm8xxx_led_blink_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8xxx_led_data *ldata;
	int val;

	val = -1;
	sscanf(buf, "%u", &val);
	if (val < 0 || val > 255)
		return -EINVAL;

	led_cdev = (struct led_classdev *) dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8xxx_led_data, cdev);

	LED_INFO("%s: bank %d blink %d\n", __func__, ldata->bank, val);

	switch (val) {
	case BLINK_STOP:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(0);
		pwm_disable(ldata->pwm_led);
		break;
	case BLINK_UNCHANGE:
		pwm_disable(ldata->pwm_led);
		if (led_cdev->brightness) {
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(1);
			pwm_config(ldata->pwm_led, 64000, 64000);
			pwm_enable(ldata->pwm_led);
		} else {
			pwm_disable(ldata->pwm_led);
			if (ldata->gpio_status_switch != NULL)
				ldata->gpio_status_switch(0);
		}
		break;
	case BLINK_64MS_PER_2SEC:
		if (ldata->gpio_status_switch != NULL)
			ldata->gpio_status_switch(1);
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 64000, 2000000);
		pwm_enable(ldata->pwm_led);
		break;
	case BLINK_64MS_ON_310MS_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(310));
		break;
	case BLINK_64MS_ON_2SEC_PER_2SEC:
		cancel_delayed_work_sync(&ldata->blink_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->blink_delayed_work,
				   msecs_to_jiffies(1000));
		break;
	case BLINK_1SEC_PER_2SEC:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 1000000, 2000000);
		pwm_enable(ldata->pwm_led);
		break;
	default:
		LED_ERR("%s: bank %d did not support blink type %d\n", __func__, ldata->bank, val);
		return -EINVAL;
	}

	return count;
}
void mcu_main()
{
	// by default, the edison has ID 0
	int edisonID = 0;
	// if we pass in an argument, use it for the edisonID
	// please pass in an integer
	//if (argc == 2) {
		//edisonID = atoi(argv[1]);
	//}

	int temp;
	while (1)
	{

		//int host_receive(unsigned char *buf, int length)
		temp = host_receive((unsigned char *)host_message, BUFFER_LENGTH);
		if (temp > 0)
		{
			debug_print(DBG_INFO, "Received a Message!\n");
            host_send((unsigned char*)"hello mcu\n", 10);
            preamble_length = host_message[0];
		}

		// Preamble - Signals the Receiver Message Incoming
		send_preamble_sequence(preamble_length);

		// Sending Edison Board ID # - 2 bits, MSB then LSB
		switch (edisonID) {
			case 0:
				send_low_bit();	// Send lsb bit 0 = LOW
				send_low_bit();	// Send msb bit 1 = LOW
				break;
			case 1:
				send_high_bit();	// Send lsb bit 0 = HIGH
				send_low_bit();	// Send msb bit 1 = LOW
				break;
			case 2:
				send_low_bit();	// Send lsb bit 0 = LOW
				send_high_bit();	// Send msb bit 1 =
				break;
			case 3:
				send_high_bit();	// Send lsb bit 0 = HIGH
				send_high_bit();	// Send msb bit 1 = HIGH
				break;
			default:
				send_low_bit();	// Send lsb bit 0 = LOW
				send_low_bit();	// Send msb bit 1 = LOW
		}

		// Sending Edison IR Emitter ID # - 2 bits, MSB then LSB

		// pwm1 = 00 = short-long/short-long = 5-20/5-20
		// pwm2 = 01 = short-long/long-short = 5-20/20-5
		// pwm3 = 10 = long-short/short-long = 20-5/5-20
		// pwm4 = 11 = long-short/long-short = 20-5/20-5

		// First Bit
		pwm_configure(pwm1, MESSAGE_DUTY_LOW, MESSAGE_PERIOD); 	// 0
		pwm_configure(pwm2, MESSAGE_DUTY_LOW, MESSAGE_PERIOD); 	// 0
		pwm_configure(pwm3, MESSAGE_DUTY_HIGH, MESSAGE_PERIOD); // 1
		pwm_configure(pwm4, MESSAGE_DUTY_HIGH, MESSAGE_PERIOD); // 1

		pwm_enable(pwm1);
		pwm_enable(pwm2);
		pwm_enable(pwm3);
		pwm_enable(pwm4);

		mcu_delay(MESSAGE_SLEEP);

		// Second Bit
		pwm_configure(pwm1, MESSAGE_DUTY_LOW, MESSAGE_PERIOD); 	// 0
		pwm_configure(pwm2, MESSAGE_DUTY_HIGH, MESSAGE_PERIOD); // 1
		pwm_configure(pwm3, MESSAGE_DUTY_LOW, MESSAGE_PERIOD); 	// 0
		pwm_configure(pwm4, MESSAGE_DUTY_HIGH, MESSAGE_PERIOD); // 1

		pwm_enable(pwm1);
		pwm_enable(pwm2);
		pwm_enable(pwm3);
		pwm_enable(pwm4);

		mcu_delay(MESSAGE_SLEEP);
	}


}
Beispiel #16
0
int display_init(void *lcdbase, int fb_bits_per_pixel,
		 struct display_timing *timing)
{
	struct dc_ctlr *dc_ctlr;
	const void *blob = gd->fdt_blob;
	struct udevice *dp_dev;
	const int href_to_sync = 1, vref_to_sync = 1;
	int panel_bpp = 18;	/* default 18 bits per pixel */
	u32 plld_rate;
	struct gpio_desc vdd_gpio, enable_gpio;
	int pwm;
	int node;
	int ret;

	ret = uclass_get_device(UCLASS_DISPLAY, 0, &dp_dev);
	if (ret)
		return ret;

	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_DC);
	if (node < 0)
		return -ENOENT;
	dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg");
	if (fdtdec_decode_display_timing(blob, node, 0, timing))
		return -EINVAL;

	ret = display_update_config_from_edid(dp_dev, &panel_bpp, timing);
	if (ret) {
		debug("%s: Failed to decode EDID, using defaults\n", __func__);
		dump_config(panel_bpp, timing);
	}

	if (!get_backlight_info(blob, &vdd_gpio, &enable_gpio, &pwm)) {
		dm_gpio_set_value(&vdd_gpio, 1);
		debug("%s: backlight vdd setting gpio %08x to %d\n",
		      __func__, gpio_get_number(&vdd_gpio), 1);
	}

	/*
	 * The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
	 * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
	 * update_display_mode() for detail.
	 */
	plld_rate = clock_set_display_rate(timing->pixelclock.typ * 2);
	if (plld_rate == 0) {
		printf("dc: clock init failed\n");
		return -EIO;
	} else if (plld_rate != timing->pixelclock.typ * 2) {
		debug("dc: plld rounded to %u\n", plld_rate);
		timing->pixelclock.typ = plld_rate / 2;
	}

	/* Init dc */
	ret = tegra_dc_init(dc_ctlr);
	if (ret) {
		debug("dc: init failed\n");
		return ret;
	}

	/* Configure dc mode */
	ret = update_display_mode(dc_ctlr, timing, href_to_sync, vref_to_sync);
	if (ret) {
		debug("dc: failed to configure display mode\n");
		return ret;
	}

	/* Enable dp */
	ret = display_enable(dp_dev, panel_bpp, timing);
	if (ret)
		return ret;

	ret = update_window(dc_ctlr, (ulong)lcdbase, fb_bits_per_pixel, timing);
	if (ret)
		return ret;

	/* Set up Tegra PWM to drive the panel backlight */
	pwm_enable(pwm, 0, 220, 0x2e);
	udelay(10 * 1000);

	if (dm_gpio_is_valid(&enable_gpio)) {
		dm_gpio_set_value(&enable_gpio, 1);
		debug("%s: backlight enable setting gpio %08x to %d\n",
		      __func__, gpio_get_number(&enable_gpio), 1);
	}

	return 0;
}
Beispiel #17
0
extern void pm8xxx_led_current_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
    struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	int rc, offset;
	u8 level;

	int *pduties;

	LED_INFO("%s, bank:%d, brightness:%d\n", __func__, led->bank, brightness);
	cancel_delayed_work_sync(&led->fade_delayed_work);
	virtual_key_state = brightness;
	if (flag_hold_virtual_key == 1) {
		LED_INFO("%s, key control \n", __func__);
		return;
	}

	if(brightness) {
		level = (led->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
		offset = PM8XXX_LED_OFFSET(led->id);
		led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
		led->reg |= level;
		rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
		if (rc)
			LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);

		if (led->function_flags & LED_BRETH_FUNCTION) {
			pduties = led->duties;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
		} else {
			pwm_config(led->pwm_led, 64000, 64000);
			pwm_enable(led->pwm_led);
		}
	} else {
		if (led->function_flags & LED_BRETH_FUNCTION) {
			wake_lock_timeout(&pmic_led_wake_lock, HZ*2);
			pduties = led->duties + led->duites_size;
			pm8xxx_pwm_lut_config(led->pwm_led,
						led->period_us,
						pduties,
						led->duty_time_ms,
						led->start_index,
						led->duites_size,
						0, 0,
						led->lut_flag);
			pm8xxx_pwm_lut_enable(led->pwm_led, 0);
			pm8xxx_pwm_lut_enable(led->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
						&led->fade_delayed_work,
						msecs_to_jiffies(led->duty_time_ms*led->duites_size));
		} else {
			pwm_disable(led->pwm_led);
			level = (0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(led->id);
			led->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			led->reg |= level;
			rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), led->reg);
			if (rc)
				LED_ERR("%s can't set (%d) led value rc=%d\n", __func__, led->id, rc);
		}
	}
	// checking for buttons device
	if (led_cdev_buttons == led_cdev)
	{
		printk("[BB] led_current_set %d \n", brightness);
		if (brightness>0)
		{
			// screen turning off together with buttons led
			buttons_turning_on_with_screen_on = 1;
		} else
		{
			// screen turning off together without buttons led
			buttons_turning_on_with_screen_on = 0;
		}
	}
	// no blink needed
	pm8xxx_led_current_set_flagged( led_cdev, brightness, 0);
}
Beispiel #18
0
/**
 * Handle the next stage of device init
 */
static int handle_stage(const void *blob)
{
	debug("%s: stage %d\n", __func__, stage);

	/* do the things for this stage */
	switch (stage) {
	case STAGE_START:
		/* Initialize the Tegra display controller */
		if (tegra_display_probe(gd->fdt_blob, (void *)gd->fb_base)) {
			printf("%s: Failed to probe display driver\n",
			__func__);
			return -1;
		}

		/* get panel details */
		if (fdt_decode_lcd(blob, &config)) {
			printf("No valid LCD information in device tree\n");
			return -1;
		}

		/*
		 * It is possible that the FDT has requested that the LCD be
		 * disabled. We currently don't support this. It would require
		 * changes to U-Boot LCD subsystem to have LCD support
		 * compiled in but not used. An easier option might be to
		 * still have a frame buffer, but leave the backlight off and
		 * remove all mention of lcd in the stdout environment
		 * variable.
		 */

		funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT);
		break;
	case STAGE_PANEL_VDD:
		if (dm_gpio_is_valid(&config.panel_vdd))
			dm_gpio_set_value(&config.panel_vdd, 1);
		break;
	case STAGE_LVDS:
		if (dm_gpio_is_valid(&config.lvds_shutdown))
			dm_gpio_set_value(&config.lvds_shutdown, 1);
		break;
	case STAGE_BACKLIGHT_VDD:
		if (dm_gpio_is_valid(&config.backlight_vdd))
			dm_gpio_set_value(&config.backlight_vdd, 1);
		break;
	case STAGE_PWM:
		/* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
		pinmux_set_func(PMUX_PINGRP_GPU, PMUX_FUNC_PWM);
		pinmux_tristate_disable(PMUX_PINGRP_GPU);

		pwm_enable(config.pwm_channel, 32768, 0xdf, 1);
		break;
	case STAGE_BACKLIGHT_EN:
		if (dm_gpio_is_valid(&config.backlight_en))
			dm_gpio_set_value(&config.backlight_en, 1);
		break;
	case STAGE_DONE:
		break;
	}

	/* set up timer for next stage */
	timer_next = timer_get_us();
	if (stage < FDT_LCD_TIMINGS)
		timer_next += config.panel_timings[stage] * 1000;

	/* move to next stage */
	stage++;
	return 0;
}
static void pm8xxx_led_gpio_set(struct led_classdev *led_cdev, enum led_brightness brightness)
{
	int rc, offset;
	u8 level;

	struct pm8xxx_led_data *led = container_of(led_cdev,  struct pm8xxx_led_data, cdev);
	LED_INFO("%s, bank:%d, brightness:%d sync: %d\n", __func__, led->bank, brightness, led->led_sync);
	if (led->gpio_status_switch != NULL)
		led->gpio_status_switch(0);
	pwm_disable(led->pwm_led);
	if(led->led_sync) {
		if (!strcmp(led->cdev.name, "green")){
			if (green_back_led_data->gpio_status_switch != NULL)
				green_back_led_data->gpio_status_switch(0);
			pwm_disable(green_back_led_data->pwm_led);
			level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
			green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			green_back_led_data->reg |= level;
			rc = pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
		}
		if (!strcmp(led->cdev.name, "amber")){
			if (amber_back_led_data->gpio_status_switch != NULL)
				amber_back_led_data->gpio_status_switch(0);
			pwm_disable(amber_back_led_data->pwm_led);
			level = ( 0 << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
			offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
			amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
			amber_back_led_data->reg |= level;
			rc = pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
		}
	}
	if (brightness) {
		if (led->gpio_status_switch != NULL)
			led->gpio_status_switch(1);
		pwm_config(led->pwm_led, 6400 * led->pwm_coefficient / 100, 6400);
		pwm_enable(led->pwm_led);
		if(led->led_sync) {
			if 	(!strcmp(led->cdev.name, "green")) {
				if (green_back_led_data->gpio_status_switch != NULL)
					green_back_led_data->gpio_status_switch(1);
				level = (green_back_led_data->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
				offset = PM8XXX_LED_OFFSET(green_back_led_data->id);
				green_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
				green_back_led_data->reg |= level;
				rc = pm8xxx_writeb(green_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), green_back_led_data->reg);
				pwm_config(green_back_led_data->pwm_led, 64000, 64000);
				pwm_enable(green_back_led_data->pwm_led);
			}
			if 	(!strcmp(led->cdev.name, "amber")) {
				if (amber_back_led_data->gpio_status_switch != NULL)
					amber_back_led_data->gpio_status_switch(1);
				level = (amber_back_led_data->out_current << PM8XXX_DRV_LED_CTRL_SHIFT) & PM8XXX_DRV_LED_CTRL_MASK;
				offset = PM8XXX_LED_OFFSET(amber_back_led_data->id);
				amber_back_led_data->reg &= ~PM8XXX_DRV_LED_CTRL_MASK;
				amber_back_led_data->reg |= level;
				rc = pm8xxx_writeb(amber_back_led_data->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset), amber_back_led_data->reg);
				pwm_config(amber_back_led_data->pwm_led, 64000, 64000);
				pwm_enable(amber_back_led_data->pwm_led);
			}
		}
	}
}
Beispiel #20
0
/*
 * channel: pwm channel,0/1
 * pwm_info->freq:  pwm freq, in hz
 * pwm_info->active_state: 0:low level; 1:high level
 */
__s32 pwm_set_para(__u32 channel, __pwm_info_t *pwm_info)
{
	__u32 pre_scal[10] = { 120, 180, 240, 360, 480,
			       12000, 24000, 36000, 48000, 72000 };
	__u32 pre_scal_id = 0, entire_cycle = 256, active_cycle = 192;
	__u32 i = 0, tmp = 0;
	__u32 freq;

	freq = 1000000 / pwm_info->period_ns;

	if (freq > 200000) {
		DE_WRN("pwm preq is large then 200khz, fix to 200khz\n");
		freq = 200000;
	}

	if (freq > 781) {
		pre_scal_id = 0;
		entire_cycle =
		    (24000000 / pre_scal[pre_scal_id] + (freq / 2)) / freq;
		DE_INF("pre_scal:%d, entire_cycle:%d, pwm_freq:%d\n",
		       pre_scal[i], entire_cycle,
		       24000000 / pre_scal[pre_scal_id] / entire_cycle);
	} else {
		for (i = 0; i < 10; i++) {
			__u32 pwm_freq = 0;

			pwm_freq = 24000000 / (pre_scal[i] * 256);
			if (abs(pwm_freq - freq) < abs(tmp - freq)) {
				tmp = pwm_freq;
				pre_scal_id = i;
				entire_cycle = 256;
				DE_INF("pre_scal:%d, entire_cycle:%d, "
				       "pwm_freq:%d\n", pre_scal[i], 256,
				       pwm_freq);
				DE_INF("----%d\n", tmp);
			}
		}
	}
	active_cycle = (pwm_info->duty_ns * entire_cycle +
			(pwm_info->period_ns / 2)) / pwm_info->period_ns;

	gdisp.pwm[channel].enable = pwm_info->enable;
	gdisp.pwm[channel].freq = freq;
	gdisp.pwm[channel].pre_scal = pre_scal[pre_scal_id];
	gdisp.pwm[channel].active_state = pwm_info->active_state;
	gdisp.pwm[channel].duty_ns = pwm_info->duty_ns;
	gdisp.pwm[channel].period_ns = pwm_info->period_ns;
	gdisp.pwm[channel].entire_cycle = entire_cycle;
	gdisp.pwm[channel].active_cycle = active_cycle;

	if (pre_scal_id >= 5)
		pre_scal_id += 3;

	if (channel == 0) {
		pwm_write_reg(0x204, ((entire_cycle - 1) << 16) | active_cycle);

		tmp = pwm_read_reg(0x200) & 0xffffff00;
		/*
		 * bit6: gating the special clock for pwm0
		 * bit5: pwm0: active state is high level
		 */
		tmp |= (1 << 6) | (pwm_info->active_state << 5) | pre_scal_id;
		pwm_write_reg(0x200, tmp);
	} else {
		pwm_write_reg(0x208, ((entire_cycle - 1) << 16) | active_cycle);

		tmp = pwm_read_reg(0x200) & 0xff807fff;
		/*
		 * bit21: gating the special clock for pwm1
		 * bit20: pwm1:  active state is high level
		 */
		tmp |= (1 << 21) | (pwm_info->active_state << 20) |
			(pre_scal_id << 15);
		pwm_write_reg(0x200, tmp);
	}

	pwm_enable(channel, pwm_info->enable);

	return 0;
}
Beispiel #21
0
int main (void)
{
    // Configure pins to the default states.
    config_pin_defaults();

    // Initialize the watchdog module.
    watchdog_init();

    // First, initialize registers that control servo operation.
    registers_init();

    // Initialize the PWM module.
    pwm_init();

    // Initialize the ADC module.
    adc_init();

    // Initialize the PID algorithm module.
    pid_init();

#if CURVE_MOTION_ENABLED
    // Initialize curve motion module.
    motion_init();
#endif

    // Initialize the power module.
    power_init();

#if PULSE_CONTROL_ENABLED
    pulse_control_init();
#endif

#if ENCODER_ENABLED
    // Initialize software I2C to talk with encoder.
    swi2c_init();
#endif

    // Initialize the TWI slave module.
    twi_slave_init(registers_read_byte(REG_TWI_ADDRESS));

    // Finally initialize the timer.
    timer_set(0);

    // Enable interrupts.
    sei();

    // Wait until initial position value is ready.
    {
        int16_t position;
        // Get start-up position
#if ENCODER_ENABLED
        position=(int16_t) enc_get_position_value();
#else
        while (!adc_position_value_is_ready());
        position=(int16_t) adc_get_position_value();
#endif

#if CURVE_MOTION_ENABLED
        // Reset the curve motion with the current position of the servo.
        motion_reset(position);
#endif

        // Set the initial seek position and velocity.
        registers_write_word(REG_SEEK_POSITION_HI, REG_SEEK_POSITION_LO, position);
        registers_write_word(REG_SEEK_VELOCITY_HI, REG_SEEK_VELOCITY_LO, 0);
    }


    // XXX Enable PWM and writing.  I do this for now to make development and
    // XXX tuning a bit easier.  Constantly manually setting these values to
    // XXX turn the servo on and write the gain values get's to be a pain.
    pwm_enable();
    registers_write_enable();

    // This is the main processing loop for the servo.  It basically looks
    // for new position, power or TWI commands to be processed.
    for (;;)
    {
        uint8_t tick;
        int16_t pwm;
        int16_t position;
        // Is ADC position value ready?
        // NOTE: Even when the encoder is enabled, we still need the ADC potmeasurement as the
        //       clock because that is how the original firmware was written.
        tick=adc_position_value_is_ready();
        if(tick)
        {
#if PULSE_CONTROL_ENABLED
            // Give pulse control a chance to update the seek position.
            pulse_control_update();
#endif

#if CURVE_MOTION_ENABLED
            // Give the motion curve a chance to update the seek position and velocity.
            motion_next(10);
#endif
        }

        // Get the new position value.
        if(tick)
        {
            position = (int16_t) adc_get_position_value(); // NOTE: For encoder builds, this is the clock: clear the flag
#if ENCODER_ENABLED
        } // Always run the encoder (faster PID to PWM loop = better?)
        position = (int16_t) enc_get_position_value();
        if (position >= 0)
        {
#endif
            // Call the PID algorithm module to get a new PWM value.
            pwm = pid_position_to_pwm(position, tick);

            // Update the servo movement as indicated by the PWM value.
            // Sanity checks are performed against the position value.
            pwm_update(position, pwm);
        }

        // Is a power value ready?
        if (adc_power_value_is_ready())
        {
            // Get the new power value.
            uint16_t power = adc_get_power_value();

            // Update the power value for reporting.
            power_update(power);
        }

        // Was a command recieved?
        if (twi_data_in_receive_buffer())
        {
            // Handle any TWI command.
            handle_twi_command();
        }

#if MAIN_MOTION_TEST_ENABLED
        // This code is in place for having the servo drive itself between
        // two positions to aid in the servo tuning process.  This code
        // should normally be disabled in config.h.
#if CURVE_MOTION_ENABLED
        if (motion_time_left() == 0)
        {
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 2000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0100);
            motion_append();
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 1000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0300);
            motion_append();
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 2000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0300);
            motion_append();
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 1000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0100);
            motion_append();
        }
#else
        {
            // Get the timer.
            uint16_t timer = timer_get();

            // Reset the timer if greater than 800.
            if (timer > 800) timer_set(0);

            // Look for specific events.
            if (timer == 0)
            {
                registers_write_word(REG_SEEK_HI, REG_SEEK_LO, 0x0100);
            }
            else if (timer == 400)
            {
                registers_write_word(REG_SEEK_HI, REG_SEEK_LO, 0x0300);
            }
        }
#endif
#endif
    }

    return 0;
}
Beispiel #22
0
/*
 * channel: pwm channel,0/1
 * pwm_info->freq:  pwm freq, in hz
 * pwm_info->active_state: 0:low level; 1:high level
 */
__s32 pwm_set_para(__u32 channel, __pwm_info_t *pwm_info)
{
	__u32 pre_scal[11][2] = {
		{1, 0xf},
		{120, 0}, {180, 1}, {240, 2}, {360, 3}, {480, 4},
		{12000, 8}, {24000, 9}, {36000, 0xa},
		{48000, 0xb}, {72000, 0xc}
	};
	__u32 pre_scal_id = 0, entire_cycle = 16, active_cycle = 12;
	__u32 i = 0, j = 0, tmp = 0;
	__u32 freq;

	freq = 1000000 / pwm_info->period_ns;

	if (freq > 366) {
		pre_scal_id = 0;
		entire_cycle = 24000000 / freq;
	} else {
		for (i = 1; i < 11; i++) {
			for (j = 16;; j += 16) {
				__u32 pwm_freq = 0;

				pwm_freq = 24000000 / (pre_scal[i][0] * j);
				if (abs(pwm_freq - freq) < abs(tmp - freq)) {
					tmp = pwm_freq;
					pre_scal_id = i;
					entire_cycle = j;
					DE_INF("pre_scal:%d, entire_cycle:%d, "
					       "pwm_freq:%d\n",
					       pre_scal[i][0], j, pwm_freq);
					DE_INF("----%d\n", tmp);
				} else if ((tmp < freq) && (pwm_freq < tmp)) {
					break;
				}
			}
		}
	}

	active_cycle = (pwm_info->duty_ns * entire_cycle +
			(pwm_info->period_ns / 2)) / pwm_info->period_ns;

	gdisp.pwm[channel].enable = pwm_info->enable;
	gdisp.pwm[channel].freq = freq;
	gdisp.pwm[channel].pre_scal = pre_scal[pre_scal_id][0];
	gdisp.pwm[channel].active_state = pwm_info->active_state;
	gdisp.pwm[channel].duty_ns = pwm_info->duty_ns;
	gdisp.pwm[channel].period_ns = pwm_info->period_ns;
	gdisp.pwm[channel].entire_cycle = entire_cycle;
	gdisp.pwm[channel].active_cycle = active_cycle;

	if (channel == 0) {
		pwm_write_reg(0x204, ((entire_cycle - 1) << 16) | active_cycle);

		tmp = pwm_read_reg(0x200) & 0xffffff00;
		/*
		 * bit6: gating the special clock for pwm0
		 * bit5: pwm0: active state is high level
		 */
		tmp |= ((1 << 6) | (pwm_info->active_state << 5) |
			pre_scal[pre_scal_id][1]);
		pwm_write_reg(0x200, tmp);
	} else {
		pwm_write_reg(0x208, ((entire_cycle - 1) << 16) | active_cycle);

		tmp = pwm_read_reg(0x200) & 0xff807fff;
		/*
		 * bit21: gating the special clock for pwm1
		 * bit20: pwm1: active state is high level
		 */
		tmp |= ((1 << 21) | (pwm_info->active_state << 20) |
			(pre_scal[pre_scal_id][1] << 15));
		pwm_write_reg(0x200, tmp);
	}

	pwm_enable(channel, pwm_info->enable);

	return 0;
}
static void haptic_work(struct work_struct *work)
{
	struct max77833_haptic_data *hap_data
		= container_of(work, struct max77833_haptic_data, work);
	int error = 0, temperature_level;

	pr_info("[VIB] %s\n", __func__);
	if (hap_data->timeout > 0) {
		if (hap_data->running)
			return;
		max77833_haptic_i2c(hap_data, true);

		temperature_level = temperature_check();

		if (temperature_level != prev_temperature_level) {
			switch(temperature_level)
			{
				case 0:
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_MIN_FREQ_LOW, hap_data->pdata->auto_res_min_low_low_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
					}
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_MAX_FREQ_LOW, hap_data->pdata->auto_res_max_low_low_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
					}
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_INIT_GUESS_LOW, hap_data->pdata->auto_res_init_low_low_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
					}
					break;
				case 1:
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_MIN_FREQ_LOW, hap_data->pdata->auto_res_min_low);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
					}
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_MAX_FREQ_LOW, hap_data->pdata->auto_res_max_low);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
					}
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_INIT_GUESS_LOW, hap_data->pdata->auto_res_init_low);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
					}
					break;
				case 2:
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_MIN_FREQ_LOW, hap_data->pdata->auto_res_min_low_high_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
					}
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_MAX_FREQ_LOW, hap_data->pdata->auto_res_max_low_high_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
					}
					error = max77833_write_reg(hap_data->i2c,
						MAX77833_AUTORES_INIT_GUESS_LOW, hap_data->pdata->auto_res_init_low_high_temp);
					if (error < 0) {
						pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
						__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
					}
					break;
				default:
					pr_err("[VIB] %s Failed to read temperature [%d]\n",
					__func__, temperature_level);
					break;
			}
		}

		prev_temperature_level = temperature_level;

		pwm_config(hap_data->pwm, hap_data->pdata->duty,
				hap_data->pdata->period);
		pwm_enable(hap_data->pwm);
		hap_data->running = true;
	} else {
		if (!hap_data->running)
			return;

		pwm_disable(hap_data->pwm);
		max77833_haptic_i2c(hap_data, false);
		hap_data->running = false;
	}
	return;
}
Beispiel #24
0
static void pwm_kblight_lid_change(void)
{
	pwm_enable(PWM_CH_KBLIGHT, lid_is_open());
}
static void pm8058_drvx_led_brightness_set(struct led_classdev *led_cdev,
					   enum led_brightness brightness)
{
	struct pm8058_led_data *ldata;
	int *pduties;
	int id, mode;
	int milliamps;

	ldata = container_of(led_cdev, struct pm8058_led_data, ldev);

	pwm_disable(ldata->pwm_led);
	cancel_delayed_work_sync(&ldata->led_delayed_work);

	id = bank_to_id(ldata->bank);
	mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 :
					PM_PWM_CONF_PWM1 + (ldata->bank - 4);

	brightness = (brightness > LED_FULL) ? LED_FULL : brightness;
	brightness = (brightness < LED_OFF) ? LED_OFF : brightness;
	printk(KERN_INFO "%s: bank %d brightness %d +\n", __func__,
	       ldata->bank, brightness);

	if (brightness) {
		milliamps = (ldata->flags & PM8058_LED_DYNAMIC_BRIGHTNESS_EN) ?
			    ldata->out_current * brightness / LED_FULL :
			    ldata->out_current;
		pm8058_pwm_config_led(ldata->pwm_led, id, mode, milliamps);
		if (ldata->flags & PM8058_LED_LTU_EN) {
			pduties = &duties[ldata->start_index];
			pm8058_pwm_lut_config(ldata->pwm_led,
					      ldata->period_us,
					      pduties,
					      ldata->duty_time_ms,
					      ldata->start_index,
					      ldata->duites_size,
					      0, 0,
					      ldata->lut_flag);
			pm8058_pwm_lut_enable(ldata->pwm_led, 0);
			pm8058_pwm_lut_enable(ldata->pwm_led, 1);
		} else {
			pwm_config(ldata->pwm_led, 64000, 64000);
			pwm_enable(ldata->pwm_led);
		}
	} else {
		if (ldata->flags & PM8058_LED_LTU_EN) {
			wake_lock(&pmic_led_wake_lock);
			pduties = &duties[ldata->start_index +
					  ldata->duites_size];
			pm8058_pwm_lut_config(ldata->pwm_led,
					      ldata->period_us,
					      pduties,
					      ldata->duty_time_ms,
					      ldata->start_index +
					      ldata->duites_size,
					      ldata->duites_size,
					      0, 0,
					      ldata->lut_flag);
			pm8058_pwm_lut_enable(ldata->pwm_led, 1);
			queue_delayed_work(g_led_work_queue,
					   &ldata->led_delayed_work,
					   msecs_to_jiffies(ldata->duty_time_ms * ldata->duty_time_ms));

			printk(KERN_INFO "%s: bank %d fade out brightness %d -\n", __func__,
			ldata->bank, brightness);
			return;
		} else
			pwm_disable(ldata->pwm_led);
		pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0);
	}
	printk(KERN_INFO "%s: bank %d brightness %d -\n", __func__, ldata->bank, brightness);
}
Beispiel #26
0
int main (void)
{
	// Configure pins to the default states.
	config_pin_defaults();

    // Initialize the watchdog module.
    watchdog_init();

    // First, initialize registers that control servo operation.
    registers_init();

    // Initialize the PWM module.
    pwm_init();

    // Initialize the ADC module.
    adc_init();

#if ESTIMATOR_ENABLED
    // Initialize the state estimator module.
    estimator_init();
#endif

#if REGULATOR_MOTION_ENABLED
    // Initialize the regulator algorithm module.
    regulator_init();
#endif

#if PID_MOTION_ENABLED
    // Initialize the PID algorithm module.
    pid_init();
#endif

#if IPD_MOTION_ENABLED
    // Initialize the IPD algorithm module.
    ipd_init();
#endif

#if CURVE_MOTION_ENABLED
    // Initialize curve motion module.
    motion_init();
#endif

    // Initialize the power module.
    power_init();

#if PULSE_CONTROL_ENABLED
    pulse_control_init();
#endif

    // Initialize the TWI slave module.
    twi_slave_init(registers_read_byte(REG_TWI_ADDRESS));

    // Finally initialize the timer.
    timer_set(0);

    // Enable interrupts.
    sei();

    // Wait until initial position value is ready.
    while (!adc_position_value_is_ready());

#if CURVE_MOTION_ENABLED
    // Reset the curve motion with the current position of the servo.
    motion_reset(adc_get_position_value());
#endif

    // Set the initial seek position and velocity.
    registers_write_word(REG_SEEK_POSITION_HI, REG_SEEK_POSITION_LO, adc_get_position_value());
    registers_write_word(REG_SEEK_VELOCITY_HI, REG_SEEK_VELOCITY_LO, 0);

    // XXX Enable PWM and writing.  I do this for now to make development and
    // XXX tuning a bit easier.  Constantly manually setting these values to 
    // XXX turn the servo on and write the gain values get's to be a pain.
    pwm_enable();
    registers_write_enable();

    // This is the main processing loop for the servo.  It basically looks
    // for new position, power or TWI commands to be processed.
    for (;;)
    {
        // Is position value ready?
        if (adc_position_value_is_ready())
        {
            int16_t pwm;
            int16_t position;

#if PULSE_CONTROL_ENABLED
            // Give pulse control a chance to update the seek position.
            pulse_control_update();
#endif

#if CURVE_MOTION_ENABLED
            // Give the motion curve a chance to update the seek position and velocity.
            motion_next(10);
#endif

            // Get the new position value.
            position = (int16_t) adc_get_position_value();

#if ESTIMATOR_ENABLED
            // Estimate velocity.
            estimate_velocity(position);
#endif

#if PID_MOTION_ENABLED
            // Call the PID algorithm module to get a new PWM value.
            pwm = pid_position_to_pwm(position);
#endif

#if IPD_MOTION_ENABLED
            // Call the IPD algorithm module to get a new PWM value.
            pwm = ipd_position_to_pwm(position);
#endif

#if REGULATOR_MOTION_ENABLED
            // Call the state regulator algorithm module to get a new PWM value.
            pwm = regulator_position_to_pwm(position);
#endif

            // Update the servo movement as indicated by the PWM value.
            // Sanity checks are performed against the position value.
            pwm_update(position, pwm);
        }

        // Is a power value ready?
        if (adc_power_value_is_ready())
        {
            // Get the new power value.
            uint16_t power = adc_get_power_value();

            // Update the power value for reporting.
            power_update(power);
        }

        // Was a command recieved?
        if (twi_data_in_receive_buffer())
        {
            // Handle any TWI command.
            handle_twi_command();
        }

#if MAIN_MOTION_TEST_ENABLED
        // This code is in place for having the servo drive itself between 
        // two positions to aid in the servo tuning process.  This code 
        // should normally be disabled in config.h.
#if CURVE_MOTION_ENABLED
        if (motion_time_left() == 0)
        {
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 2000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0100);
            motion_append();
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 1000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0300);
            motion_append();
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 2000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0300);
            motion_append();
            registers_write_word(REG_CURVE_DELTA_HI, REG_CURVE_DELTA_LO, 1000);
            registers_write_word(REG_CURVE_POSITION_HI, REG_CURVE_POSITION_LO, 0x0100);
            motion_append();
        }
#else
        {
            // Get the timer.
            uint16_t timer = timer_get();

            // Reset the timer if greater than 800.
            if (timer > 800) timer_set(0);

            // Look for specific events.
            if (timer == 0)
            {
                registers_write_word(REG_SEEK_HI, REG_SEEK_LO, 0x0100);
            }
            else if (timer == 400)
            {
                registers_write_word(REG_SEEK_HI, REG_SEEK_LO, 0x0300);
            }
        }
#endif
#endif
    }

    return 0;
}
static int pm8058_led_probe(struct platform_device *pdev)
{
	struct pm8058_led_platform_data *pdata;
	struct pm8058_led_data *ldata;
	int i, ret;

	ret = -ENOMEM;

	pdata = pdev->dev.platform_data;

	if (pdata == NULL) {
		pr_err("%s: platform data is NULL\n", __func__);
		return -ENODEV;
	}

	if (!pdata->num_leds) {
		pr_err("%s: LED num is 0\n", __func__);
		return 0;
	}

	ldata = kzalloc(sizeof(struct pm8058_led_data)
			* pdata->num_leds, GFP_KERNEL);
	if (ldata == NULL) {
		ret = -ENOMEM;
		pr_err("%s: failed on allocate ldata\n", __func__);
		goto err_exit;
	}

	dev_set_drvdata(&pdev->dev, ldata);

	wake_lock_init(&pmic_led_wake_lock, WAKE_LOCK_SUSPEND, "pmic_led");

	g_led_work_queue = create_workqueue("led");
	if (!g_led_work_queue)
		goto err_create_work_queue;

	for (i = 0; i < 64; i++)
		duties[i] = pdata->duties[i];

	for (i = 0; i < pdata->num_leds; i++) {
		ldata[i].led_config = pdata->led_config + i;
		ldata[i].ldev.name = pdata->led_config[i].name;
		ldata[i].bank = pdata->led_config[i].bank;
		ldata[i].flags =  pdata->led_config[i].flags;
		ldata[i].pwm_size =  pdata->led_config[i].pwm_size;
		ldata[i].clk =  pdata->led_config[i].clk;
		ldata[i].pre_div =  pdata->led_config[i].pre_div;
		ldata[i].pre_div_exp =  pdata->led_config[i].pre_div_exp;
		ldata[i].pwm_value =  pdata->led_config[i].pwm_value;
		ldata[i].period_us =  pdata->led_config[i].period_us;
		ldata[i].start_index =  pdata->led_config[i].start_index;
		ldata[i].duites_size =  pdata->led_config[i].duites_size;
		ldata[i].duty_time_ms =  pdata->led_config[i].duty_time_ms;
		ldata[i].lut_flag =  pdata->led_config[i].lut_flag;
		ldata[i].out_current =  pdata->led_config[i].out_current;
		switch (pdata->led_config[i].type) {
		case PM8058_LED_CURRENT:
			if (ldata[i].flags & PM8058_LED_BLINK_EN)
				INIT_DELAYED_WORK(&ldata[i].led_delayed_work,
						  led_blink_do_work);
			else
				INIT_DELAYED_WORK(&ldata[i].led_delayed_work,
						  pwm_lut_delayed_fade_out);
			ldata[i].pwm_led = pwm_request(ldata[i].bank,
						ldata[i].ldev.name);
			ldata[i].ldev.brightness_set =
					pm8058_drvx_led_brightness_set;
			break;
		case PM8058_LED_RGB:
			INIT_DELAYED_WORK(&ldata[i].led_delayed_work,
					  led_blink_do_work);
		case PM8058_LED_PWM:
			ldata[i].pwm_led = pwm_request(ldata[i].bank,
						       ldata[i].ldev.name);
			ldata[i].ldev.brightness_set =
					pm8058_pwm_led_brightness_set;
			break;
		case PM8058_LED_DRVX:
			if (ldata[i].flags & PM8058_LED_BLINK_EN)
				INIT_DELAYED_WORK(&ldata[i].led_delayed_work,
						  led_blink_do_work);
			else
				INIT_DELAYED_WORK(&ldata[i].led_delayed_work,
						  pwm_lut_delayed_fade_out);
			ldata[i].pwm_led = pwm_request(ldata[i].bank,
						ldata[i].ldev.name);
			ldata[i].ldev.brightness_set =
					pm8058_drvx_led_brightness_set;
			break;
		}

		if (ldata[i].bank == 6) {
			if (board_mfg_mode() == 0) {
				pwm_config(ldata[i].pwm_led, 64000, 64000);
				pwm_enable(ldata[i].pwm_led);
			} else {
				pwm_disable(ldata->pwm_led);
				pm8058_pwm_config_led(ldata->pwm_led, 2, 3, 0);
			}
		}

		ret = led_classdev_register(&pdev->dev, &ldata[i].ldev);
		if (ret < 0) {
			pr_err("%s: failed on led_classdev_register [%s]\n",
				__func__, ldata[i].ldev.name);
			goto err_register_led_cdev;
		}
	}

	for (i = 0; i < pdata->num_leds; i++) {
		if (pdata->led_config[i].type == PM8058_LED_RGB ||
		    ldata[i].flags & PM8058_LED_BLINK_EN) {
			ret = device_create_file(ldata[i].ldev.dev,
						 &dev_attr_blink);
			if (ret < 0) {
				pr_err("%s: Failed to create attr blink"
				       " [%d]\n", __func__, i);
				goto err_register_attr_blink;
			}
		}
	}

	for (i = 0; i < pdata->num_leds; i++) {
		if (pdata->led_config[i].type == PM8058_LED_RGB ||
		    ldata[i].flags & PM8058_LED_BLINK_EN) {
			ret = device_create_file(ldata[i].ldev.dev,
						 &dev_attr_off_timer);
			if (ret < 0) {
				pr_err("%s: Failed to create attr off timer"
				       " [%d]\n", __func__, i);
				goto err_register_attr_off_timer;
			}
			INIT_WORK(&ldata[i].led_work, led_work_func);
			alarm_init(&ldata[i].led_alarm,
				   ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP,
				   led_alarm_handler);
		}
	}

	for (i = 0; i < pdata->num_leds; i++) {
		if (ldata[i].bank < 3)
			continue;
		ret = device_create_file(ldata[i].ldev.dev, &dev_attr_currents);
		if (ret < 0) {
			pr_err("%s: Failed to create attr blink [%d]\n",
			       __func__, i);
			goto err_register_attr_currents;
		}
	}

	return 0;

err_register_attr_currents:
	for (i--; i >= 0; i--) {
		if (ldata[i].bank < 3)
			continue;
		device_remove_file(ldata[i].ldev.dev, &dev_attr_currents);
	}
	i = pdata->num_leds;

err_register_attr_off_timer:
	for (i--; i >= 0; i--) {
		if (pdata->led_config[i].type == PM8058_LED_RGB ||
		    ldata[i].flags & PM8058_LED_BLINK_EN) {
			device_remove_file(ldata[i].ldev.dev,
					   &dev_attr_off_timer);
		}
	}
	i = pdata->num_leds;

err_register_attr_blink:
	for (i--; i >= 0; i--) {
		if (pdata->led_config[i].type == PM8058_LED_RGB ||
		    ldata[i].flags & PM8058_LED_BLINK_EN) {
			device_remove_file(ldata[i].ldev.dev, &dev_attr_blink);
		}
	}
	i = pdata->num_leds;

err_register_led_cdev:
	for (i--; i >= 0; i--) {
		switch (pdata->led_config[i].type) {
		case PM8058_LED_RGB:
		case PM8058_LED_PWM:
		case PM8058_LED_DRVX:
			pwm_free(ldata[i].pwm_led);
			break;
		}
		led_classdev_unregister(&ldata[i].ldev);
	}
	destroy_workqueue(g_led_work_queue);

err_create_work_queue:
	kfree(ldata);

err_exit:
	wake_lock_destroy(&pmic_led_wake_lock);
	return ret;
}
Beispiel #28
0
int main (void)
{

    SystemInit();

    adc_pin_enable(AIN0, MASK_ENABLE);
    adc_pin_enable(AIN1, MASK_ENABLE);
    
#if ADC_EXT_REF_EN==TRUE
    adc_pin_enable(AIN2, MASK_ENABLE);
    adc_pin_enable(AIN3, MASK_ENABLE);
#endif
    
#if (__AHB_CLK == 32000UL)
    uart_init(QN_UART0, __USART_CLK, UART_1200);
#else
    uart_init(QN_UART0, __USART_CLK, UART_115200);
#endif
    uart_tx_enable(QN_UART0, MASK_ENABLE);
    
    
    // ADC initialization    
#if ADC_WORKING_AT_32K==TRUE
    clk32k_enable(__32K_TYPE);
    adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK32K_16000, ADC_INT_REF, ADC_12BIT);
#else

#if ADC_EXT_REF_EN==TRUE
    adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK_1000000, ADC_EXT_REF2, ADC_12BIT);
    //adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK_1000000, ADC_EXT_REF1, ADC_12BIT);
#else    
    adc_init(ADC_SINGLE_WITHOUT_BUF_DRV, ADC_CLK_1000000, ADC_INT_REF, ADC_12BIT);
#endif
#endif
    
      
    
    // Read configuration
    adc_read_configuration read_cfg;

    
#if ADC_TRIG_BY_GPIO == TRUE

    read_cfg.trig_src = ADC_TRIG_GPIO;
    syscon_SetPMCR2WithMask(QN_SYSCON, SYSCON_MASK_ADCT_PIN_SEL, ADC_GPIO15_TRIG);

    // triger by gpio in single or single scan mode, connect PWM output to ADC trigger PIN
    pwm_init(PWM_CH0);
    pwm_config(PWM_CH0, PWM_PSCAL_DIV, PWM_COUNT_US(50, PWM_PSCAL_DIV), PWM_COUNT_US(25, PWM_PSCAL_DIV));
    pwm_enable(PWM_CH0, MASK_ENABLE);
      
#elif ADC_TRIG_BY_TOF == TRUE

    read_cfg.trig_src = ADC_TRIG_TOVF1;
    // triger by timer1 overflow
    timer_init(QN_TIMER1, NULL);
    timer_pwm_config(QN_TIMER1, TIMER_PSCAL_DIV, TIMER_COUNT_US(100, TIMER_PSCAL_DIV), TIMER_COUNT_US(50, TIMER_PSCAL_DIV));
    timer_enable(QN_TIMER1, MASK_ENABLE);

#elif ADC_TRIG_BY_SOFT == TRUE

    read_cfg.trig_src = ADC_TRIG_SOFT;

#endif


#if ADC_DECIMATION_EN == TRUE
    adc_decimation_enable(DECI_RATE_64, MASK_ENABLE);
#endif


#if ADC_COMPARATOR_EN == TRUE
    //adc_compare_init(DECI_DATA, 2500, -2000, adc_WCMP_cb);
    adc_compare_init(ADC_DATA, 600, -600, adc_WCMP_cb);
#endif


#if (ADC_TRIG_BY_GPIO==TRUE || ADC_TRIG_BY_TOF==TRUE || ADC_TRIG_BY_SOFT==TRUE)
    
    adc_done = 0;
    
    // modify here
    read_cfg.mode = SINGLE_MOD;
    read_cfg.start_ch = AIN0;
    read_cfg.end_ch = AIN0;
    adc_read(&read_cfg, buf, 512, adc_test_cb);
    while (adc_done == 0);
#endif


#if ADC_COMPARATOR_EN == TRUE
    int m = 0;
    int n = 0;
    for (int i = 0; i < 512; i++) {
        if (buf[i] > 600) {
            m++;
        }
        else if (buf[i] < -600) {
            n++;
        }
    }
    printf("m = %d\t n = %d\r\n", m, n);
#endif


    for (int i = 0; i < 512; i++) {
        printf("%d\t %d\r\n", buf[i], ADC_RESULT_mV(buf[i]));
    }
    int sum = 0;
    for (int i = 0; i < 10; i++) {
        sum += buf[511 - 2*i];
    }
    sum = sum / 10;
    printf("average: %d\t %d\r\n", sum, ADC_RESULT_mV(sum));
    


#if ADC_TEMP_SENSOR_EN==TRUE
    temp_sensor_enable(MASK_ENABLE);
    int16_t tempv;
    adc_init(ADC_DIFF_WITH_BUF_DRV, ADC_CLK_1000000, ADC_INT_REF, ADC_12BIT);
    adc_done = 0;
    read_cfg.trig_src = ADC_TRIG_SOFT;
    read_cfg.mode = SINGLE_MOD;
    read_cfg.start_ch = TEMP;
    read_cfg.end_ch = TEMP;
    adc_read(&read_cfg, &tempv, 1, adc_test_cb);
    while (adc_done == 0);
    printf("temperature: %0.1f\r\n", (float)(TEMPERATURE_X10(tempv)/10.0));
#endif


#if ADC_BATT_MONITOR_EN==TRUE
    battery_monitor_enable(MASK_ENABLE);
    int16_t battv;
    adc_init(ADC_SINGLE_WITH_BUF_DRV, ADC_CLK_1000000, ADC_INT_REF, ADC_12BIT);
    adc_done = 0;
    read_cfg.trig_src = ADC_TRIG_SOFT;
    read_cfg.mode = SINGLE_MOD;
    read_cfg.start_ch = BATT;
    read_cfg.end_ch = BATT;
    adc_read(&read_cfg, &battv, 1, adc_test_cb);
    while (adc_done == 0);
    printf("battery voltage: %d\r\n", 4*ADC_RESULT_mV(battv));
#endif
    
    
    while (1)                                /* Loop forever */
    {


    }
}
Beispiel #29
0
static ssize_t pm8058_led_blink_store(struct device *dev,
				       struct device_attribute *attr,
				       const char *buf, size_t count)
{
	struct led_classdev *led_cdev;
	struct pm8058_led_data *ldata;
	int id, mode;
	int val;
	int enable = 0;
#ifdef CONFIG_HTC_HEADSET_MISC
	int *pduties;
#endif

/*struct timespec ts1, ts2;*/

	val = -1;
	sscanf(buf, "%u", &val);
	if (val < 0 || val > 255)
		return -EINVAL;

	led_cdev = (struct led_classdev *) dev_get_drvdata(dev);
	ldata = container_of(led_cdev, struct pm8058_led_data, ldev);

	id = bank_to_id(ldata->bank);
	mode = (id == PM_PWM_LED_KPD) ? PM_PWM_CONF_PWM1 :
					PM_PWM_CONF_PWM1 + (ldata->bank - 4);

	if (ldata->flags & PM8058_LED_BLINK_EN)
		pm8058_pwm_config_led(ldata->pwm_led, id, mode,
				      ldata->out_current);

	LED_INFO_LOG("%s: bank %d blink %d\n", __func__, ldata->bank, val);

	enable = (val > 0) ? 1 : 0;
	if (strcmp(ldata->ldev.name, "charming-led") == 0)
		charming_led_enable(enable);

	switch (val) {
	case -1: /* stop flashing */
		pwm_disable(ldata->pwm_led);
		if (ldata->flags & PM8058_LED_BLINK_EN)
			pm8058_pwm_config_led(ldata->pwm_led, id, mode, 0);
		break;
	case 0:
		pwm_disable(ldata->pwm_led);
		if (led_cdev->brightness) {
			pwm_config(ldata->pwm_led, 6400 * pwm_coefficient / 100, 6400);
			pwm_enable(ldata->pwm_led);
		} else {
			if (ldata->flags & PM8058_LED_BLINK_EN)
				pm8058_pwm_config_led(ldata->pwm_led, id,
						      mode, 0);
		}
		break;
	case 1:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 64000, 2000000);
		pwm_enable(ldata->pwm_led);
		break;
	case 2:
		cancel_delayed_work_sync(&ldata->led_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work,
				   msecs_to_jiffies(310));
		break;
	case 3:
		cancel_delayed_work_sync(&ldata->led_delayed_work);
		pwm_disable(ldata->pwm_led);
		ldata->duty_time_ms = 64;
		ldata->period_us = 2000000;
		queue_delayed_work(g_led_work_queue, &ldata->led_delayed_work,
				   msecs_to_jiffies(1000));
		break;
	case 4:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 1000000, 2000000);
#if 0
		pwm_conf.pwm_size = 9;
		pwm_conf.clk = PM_PWM_CLK_1KHZ;
		pwm_conf.pre_div = PM_PWM_PREDIVIDE_2;
		pwm_conf.pre_div_exp = 1;
		pwm_conf.pwm_value = 512/2;
		pwm_conf.bypass_lut = 1;
		pwm_configure(ldata->pwm_led, &pwm_conf);
#endif
		pwm_enable(ldata->pwm_led);
		break;
	case 5:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 100000, 200000);
		pwm_enable(ldata->pwm_led);
		break;
#ifdef CONFIG_HTC_HEADSET_MISC
	case 6:
		pm8058_pwm_config_led(ldata->pwm_led, id, mode,
				      ldata->out_current);
		pduties = &duties[ldata->start_index];
		pm8058_pwm_lut_config(ldata->pwm_led, ldata->period_us,
				      pduties, ldata->duty_time_ms,
				      ldata->start_index, ldata->duites_size,
				      0, 0, ldata->lut_flag);
		pm8058_pwm_lut_enable(ldata->pwm_led, 0);
		pm8058_pwm_lut_enable(ldata->pwm_led, 1);
		break;
	case 7:
		pwm_disable(ldata->pwm_led);
		pwm_config(ldata->pwm_led, 64000, 4000000);
		pwm_enable(ldata->pwm_led);
		break;
#endif
	default:
		LED_ERR_LOG(KERN_INFO "%s: bank %d not support blink %d\n", __func__, ldata->bank, val);
		return -EINVAL;
	}
	return count;
}
Beispiel #30
0
static void servo_pwm_enable(struct servo_t * m)
{
	struct servo_pwm_pdata_t * pdat = (struct servo_pwm_pdata_t *)m->priv;
	pwm_enable(pdat->pwm);
}