static int lge_hsd_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct max1462x_platform_data *pdata = pdev->dev.platform_data;


	struct hsd_info *hi;

	HSD_DBG("lge_hsd_probe\n");

	hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL);

	if ( hi == NULL) {
		HSD_ERR("Failed to allloate headset per device info\n");
		return -ENOMEM;
	}

	if(pdev->dev.of_node){
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		pdev->dev.platform_data = pdata;

		max1462x_parse_dt(&pdev->dev,pdata);
	} else {
		pdata = devm_kzalloc(&pdev->dev,sizeof(struct max1462x_platform_data),GFP_KERNEL);
		if(!pdata){
			HSD_ERR("Failed to allocate memory\n");
			return -ENOMEM;
		}
		else
			pdata = pdev->dev.platform_data;
	}
	hi->key_code = pdata->key_code;

	platform_set_drvdata(pdev, hi);

	atomic_set(&hi->btn_state, 0);
	atomic_set(&hi->is_3_pole_or_not, 1);
	atomic_set(&hi->irq_key_enabled, FALSE);

	hi->gpio_mic_en = pdata->gpio_mic_en;
	hi->gpio_detect = pdata->gpio_detect;
	hi->gpio_key = pdata->gpio_key;
	hi->gpio_set_value_func = pdata->gpio_set_value_func;
	hi->gpio_get_value_func = pdata->gpio_get_value_func;
#ifdef CONFIG_SWITCH_MAX1462X_WA
	hi->latency_for_key = msecs_to_jiffies(80);
#else
	hi->latency_for_key = msecs_to_jiffies(50); /* convert milli to jiffies */
#endif
	mutex_init(&hi->mutex_lock);
	INIT_WORK(&hi->work, detect_work);
	INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed);
	INIT_DELAYED_WORK(&hi->work_for_key_released, button_released);
	INIT_DELAYED_WORK(&hi->work_for_key_released_remove, button_released_remove);

	ret = gpio_request(hi->gpio_mic_en, "gpio_mic_en");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_request\n", hi->gpio_mic_en);
		goto error_02;
	}

	ret = gpio_direction_output(hi->gpio_mic_en, 0);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_input\n", hi->gpio_mic_en);
		goto error_02;
	}
	HSD_DBG("gpio_get_value_cansleep(hi->gpio_mic_en) = %d\n", gpio_get_value_cansleep(hi->gpio_mic_en));

	/* init gpio_detect */
	ret = gpio_request(hi->gpio_detect, "gpio_detect");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_request\n", hi->gpio_detect);
		goto error_03;
	}

	ret = gpio_direction_input(hi->gpio_detect);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_det) gpio_direction_input\n", hi->gpio_detect);
		goto error_03;
	}

	/*init gpio_key */
	ret = gpio_request(hi->gpio_key, "gpio_key");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_request\n", hi->gpio_key);
		goto error_04;
	}

	ret = gpio_direction_input(hi->gpio_key);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_direction_input\n", hi->gpio_key);
		goto error_04;
	}


	/* initialize irq of gpio_key */
	hi->irq_key = gpio_to_irq(hi->gpio_key);

	HSD_DBG("hi->irq_key = %d\n", hi->irq_key);

	if (hi->irq_key < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_key;
		goto error_06;
	}
	ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi);
	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_06;
	}

	ret = irq_set_irq_wake(hi->irq_key, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set irq_key interrupt wake\n");
		goto error_06;
	}

	hi->irq_detect = gpio_to_irq(hi->gpio_detect);
	HSD_DBG("hi->irq_detect = %d\n", hi->irq_detect);

	if (hi->irq_detect < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_detect;
		goto error_07;
	}
	ret = request_threaded_irq(hi->irq_detect, NULL, earjack_det_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, pdev->name, hi);

	if (ret) {
		HSD_ERR("failed to request button irq\n");
		goto error_07;
	}

	ret = irq_set_irq_wake(hi->irq_detect, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set gpio_detect interrupt wake\n");
		goto error_07;
	}
	/* initialize switch device */
	hi->sdev.name = pdata->switch_name;
	hi->sdev.print_state = lge_hsd_print_state;
	hi->sdev.print_name = lge_hsd_print_name;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0) {
		HSD_ERR("Failed to register switch device\n");
		goto error_08;
	}

	/* initialize input device */
	hi->input = input_allocate_device();
	if (!hi->input) {
		HSD_ERR("Failed to allocate input device\n");
		ret = -ENOMEM;
		goto error_09;
	}

	hi->input->name = pdata->keypad_name;

	hi->input->id.vendor    = 0x0001;
	hi->input->id.product   = 1;
	hi->input->id.version   = 1;

	/* headset tx noise */
	{
		struct qpnp_vadc_result result;
		int acc_read_value = 0;
		int i, rc = 0;
		int count = 3;

		for (i = 0; i < count; i++)
		{
/* LIMIT: Include ONLY A1, B1, Vu3, Z models used MSM8974 AA/AB */
#ifdef CONFIG_ADC_READY_CHECK_JB
			rc = qpnp_vadc_read_lge(P_MUX6_1_1,&result);
#else
			/* MUST BE IMPLEMENT :
			 * After MSM8974 AC and later version(PMIC combination change),
			 * ADC AMUX of PMICs are separated in each dual PMIC.
			 *
			 * Ref.
			 * qpnp-adc-voltage.c : *qpnp_get_vadc(), qpnp_vadc_read().
			 * qpnp-charger.c     : new implementation by QCT.
			 */
#endif
			if (rc < 0)
			{
				if (rc == -ETIMEDOUT) {
					pr_err("[DEBUG]adc read timeout \n");
				} else {
					pr_err("[DEBUG]adc read error - %d\n", rc);
				}
			}
			else
			{
				acc_read_value = (int)result.physical;
				pr_info("%s: acc_read_value - %d\n", __func__, (int)result.physical);
				break;
			}
		}
	}
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(EV_SW, hi->input->evbit);
	set_bit(hi->key_code, hi->input->keybit);
	set_bit(SW_HEADPHONE_INSERT, hi->input->swbit);
	set_bit(SW_MICROPHONE_INSERT, hi->input->swbit);
	input_set_capability(hi->input, EV_KEY, KEY_MEDIA);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(hi->input, EV_KEY, KEY_VOLUMEDOWN);
	ret = input_register_device(hi->input);
	if (ret) {
		HSD_ERR("Failed to register input device\n");
		goto error_09;
	}

	if (!(hi->gpio_get_value_func(hi->gpio_detect)))

#ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE
		/* to detect in initialization with eacjack insertion */
		queue_work(local_max1462x_workqueue, &(hi->work));
#else
	/* to detect in initialization with eacjack insertion */
	schedule_work(&(hi->work));
#endif
	return ret;

error_09:
	input_free_device(hi->input);
error_08:
	switch_dev_unregister(&hi->sdev);
error_07:
	free_irq(hi->irq_detect, 0);
error_06:
	free_irq(hi->irq_key, 0);
error_04:
	gpio_free(hi->gpio_key);
error_03:
	gpio_free(hi->gpio_detect);
error_02:
	gpio_free(hi->gpio_mic_en);
	kfree(hi);
	return ret;
}
示例#2
0
static ssize_t
proximity_enable_store(struct device *dev,
			struct device_attribute *attr,
			const char *buf, size_t count)
{
	struct gp2a_data *data = dev_get_drvdata(dev);

	int value = 0;
	char input;
	int err = 0;
	int16_t thrd;
	u8 reg;

	err = kstrtoint(buf, 10, &value);

	if (err) {
		pr_err("%s, kstrtoint failed.", __func__);
		goto done;
	}
	if (value != 0 && value != 1)
		goto done;

	pr_info("%s, %d value = %d\n", __func__, __LINE__, value);

	if (data->proximity_enabled && !value) {	/* Prox power off */
		disable_irq(data->irq);

		proximity_onoff(0, data);
		disable_irq_wake(data->irq);
		//if (data->pdata->led_on)
		//	data->pdata->led_on(false);
	}
	if (!data->proximity_enabled && value) {	/* prox power on */
		//if (data->pdata->led_on)
		//	data->pdata->led_on(true);
		usleep_range(1000, 1100);
		proximity_onoff(1, data);

		err = proximity_open_calibration(data);
		if (err < 0 && err != -ENOENT)
			pr_err("%s: proximity_open_offset() failed\n",
				__func__);
		else {
			thrd = gp2a_reg[3][1]+(data->offset_value);
			THR_REG_LSB(thrd, reg);
			gp2a_i2c_write(data, gp2a_reg[3][0], &reg);
			THR_REG_MSB(thrd, reg);
			gp2a_i2c_write(data, gp2a_reg[4][0], &reg);

			thrd = gp2a_reg[5][1]+(data->offset_value);
			THR_REG_LSB(thrd, reg);
			gp2a_i2c_write(data, gp2a_reg[5][0], &reg);
			THR_REG_MSB(thrd, reg);
			gp2a_i2c_write(data, gp2a_reg[6][0], &reg);
		}

		enable_irq_wake(data->irq);
		msleep(160);

		input = gpio_get_value_cansleep(data->pdata->p_out);
		if (input == 0) {
			input_report_abs(data->proximity_input_dev,
					ABS_DISTANCE, 1);
			input_sync(data->proximity_input_dev);
		}

		enable_irq(data->irq);
	}
	data->proximity_enabled = value;
done:
	return count;
}
示例#3
0
static enum hrtimer_restart gpio_event_input_timer_func(struct hrtimer *timer)
{
	int i;
	int pressed;
	struct gpio_input_state *ds =
		container_of(timer, struct gpio_input_state, timer);
	unsigned gpio_flags = ds->info->flags;
	unsigned npolarity;
	int nkeys = ds->info->keymap_size;
	const struct gpio_event_direct_entry *key_entry;
	struct gpio_key_state *key_state;
	unsigned long irqflags;
	uint8_t debounce;
	bool sync_needed;

#if 0
	key_entry = kp->keys_info->keymap;
	key_state = kp->key_state;
	for (i = 0; i < nkeys; i++, key_entry++, key_state++)
		pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
			gpio_read_detect_status(key_entry->gpio));
#endif
	key_entry = ds->info->keymap;
	key_state = ds->key_state;
	sync_needed = false;
	spin_lock_irqsave(&ds->irq_lock, irqflags);
	for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
		debounce = key_state->debounce;
		if (debounce & DEBOUNCE_WAIT_IRQ)
			continue;
		if (key_state->debounce & DEBOUNCE_UNSTABLE) {
			debounce = key_state->debounce = DEBOUNCE_UNKNOWN;
			enable_irq(gpio_to_irq(key_entry->gpio));
			KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d "
				"(%d) continue debounce\n",
				ds->info->type, key_entry->code,
				i, key_entry->gpio);
		}
		npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
		pressed = gpio_get_value_cansleep(key_entry->gpio) ^ npolarity;

		if (debounce & DEBOUNCE_POLL) {
			if (pressed == !(debounce & DEBOUNCE_PRESSED)) {
				ds->debounce_count++;
				key_state->debounce = DEBOUNCE_UNKNOWN;
				if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
					KEY_LOGD("gpio_keys_scan_keys: key %x-"
						"%x, %d (%d) start debounce\n",
						ds->info->type, key_entry->code,
						i, key_entry->gpio);
			}
			continue;
		}
		if (pressed && (debounce & DEBOUNCE_NOTPRESSED)) {
			if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
				KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d "
					"(%d) debounce pressed 1\n",
					ds->info->type, key_entry->code,
					i, key_entry->gpio);
			key_state->debounce = DEBOUNCE_PRESSED;
			continue;
		}
		if (!pressed && (debounce & DEBOUNCE_PRESSED)) {
			if (gpio_flags & GPIOEDF_PRINT_KEY_DEBOUNCE)
				KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d "
					"(%d) debounce pressed 0\n",
					ds->info->type, key_entry->code,
					i, key_entry->gpio);
			key_state->debounce = DEBOUNCE_NOTPRESSED;
			continue;
		}
		/* key is stable */
		ds->debounce_count--;
		if (ds->use_irq)
			key_state->debounce |= DEBOUNCE_WAIT_IRQ;
		else
			key_state->debounce |= DEBOUNCE_POLL;
		if (gpio_flags & GPIOEDF_PRINT_KEYS)
			KEY_LOGD("gpio_keys_scan_keys: key %x-%x, %d (%d) "
				"changed to %d\n", ds->info->type,
				key_entry->code, i, key_entry->gpio, pressed);
#ifdef CONFIG_POWER_KEY_LED
		handle_power_key_led(key_entry->code, pressed);
#endif
		input_event(ds->input_devs->dev[key_entry->dev], ds->info->type,
			    key_entry->code, pressed);
		sync_needed = true;
	}
	if (sync_needed) {
		for (i = 0; i < ds->input_devs->count; i++)
			input_sync(ds->input_devs->dev[i]);
	}

#if 0
	key_entry = kp->keys_info->keymap;
	key_state = kp->key_state;
	for (i = 0; i < nkeys; i++, key_entry++, key_state++) {
		pr_info("gpio_read_detect_status %d %d\n", key_entry->gpio,
			gpio_read_detect_status(key_entry->gpio));
	}
#endif

	if (ds->debounce_count)
		hrtimer_start(timer, ds->info->debounce_time, HRTIMER_MODE_REL);
	else if (!ds->use_irq)
		hrtimer_start(timer, ds->info->poll_time, HRTIMER_MODE_REL);
	else
		wake_unlock(&ds->wake_lock);

	spin_unlock_irqrestore(&ds->irq_lock, irqflags);

	return HRTIMER_NORESTART;
}
示例#4
0
static void insert_headset(struct hsd_info *hi)
{
	int earjack_type;
	static int insert_first=1;

	HSD_DBG("insert_headset");

	if (hi->set_headset_mic_bias) {
		if (insert_first == 0) {
			HSD_DBG("Execute the workaround codes...\n");
			/* Workaround code for increasing sleep current */
			hi->set_headset_mic_bias(TRUE);
			msleep(5);
			hi->set_headset_mic_bias(FALSE);
			msleep(5);
			hi->set_headset_mic_bias(TRUE);
			insert_first = 0;
		} else
			hi->set_headset_mic_bias(TRUE);
	}

	gpio_set_value_cansleep(hi->gpio_mic_en, 1);

	msleep(hi->latency_for_detection);

	earjack_type = gpio_get_value_cansleep(hi->gpio_jpole);

	if (earjack_type == 1) {
		HSD_DBG("3 polarity earjack");

		if (hi->set_headset_mic_bias)
			hi->set_headset_mic_bias(FALSE);

		atomic_set(&hi->is_3_pole_or_not, 1);

		mutex_lock(&hi->mutex_lock);
		switch_set_state(&hi->sdev, LGE_HEADSET_NO_MIC);
		mutex_unlock(&hi->mutex_lock);

		gpio_set_value_cansleep(hi->gpio_mic_en, 0);

		input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1);
		input_sync(hi->input);
	} else {
		HSD_DBG("4 polarity earjack");

		atomic_set(&hi->is_3_pole_or_not, 0);

		mutex_lock(&hi->mutex_lock);
		switch_set_state(&hi->sdev, LGE_HEADSET);
		mutex_unlock(&hi->mutex_lock);

		if (!atomic_read(&hi->irq_key_enabled)) {
			unsigned long irq_flags;

			local_irq_save(irq_flags);
			enable_irq(hi->irq_key);
			local_irq_restore(irq_flags);

			atomic_set(&hi->irq_key_enabled, TRUE);
		}
		input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1);
		input_report_switch(hi->input, SW_MICROPHONE_INSERT, 1);
		input_sync(hi->input);
	}

}
示例#5
0
static int lge_hsd_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct fsa8008_platform_data *pdata = pdev->dev.platform_data;

	struct hsd_info *hi;

	HSD_DBG("lge_hsd_probe");

	hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL);

	if (NULL == hi) {
		HSD_ERR("Failed to allloate headset per device info\n");
		return -ENOMEM;
	}

	hi->key_code = pdata->key_code;

	platform_set_drvdata(pdev, hi);

	atomic_set(&hi->btn_state, 0);
	atomic_set(&hi->is_3_pole_or_not, 1);

	hi->gpio_detect = pdata->gpio_detect;
	hi->gpio_mic_en = pdata->gpio_mic_en;
	hi->gpio_jpole = pdata->gpio_jpole;
	hi->gpio_key = pdata->gpio_key;
	hi->set_headset_mic_bias = pdata->set_headset_mic_bias;

	hi->latency_for_detection = pdata->latency_for_detection;
#ifdef CONFIG_LGE_AUDIO_FSA8008_MODIFY
	hi->latency_for_key = FSA8008_KEY_PRESS_DLY_MS;
	hi->gpio_key_cnt = 0;
	INIT_DELAYED_WORK(&hi->work_for_insert, insert_headset);
	INIT_DELAYED_WORK(&hi->work_for_remove, remove_headset);
	INIT_DELAYED_WORK(&hi->work_for_key_det_enable, button_enable);
#else
	hi->latency_for_key = 200 /* milli */ * HZ / 1000; /* convert milli to jiffies */
	INIT_DELAYED_WORK(&hi->work, detect_work);
#endif
	mutex_init(&hi->mutex_lock);
	INIT_DELAYED_WORK(&hi->work_for_key_pressed, button_pressed);
	INIT_DELAYED_WORK(&hi->work_for_key_released, button_released);

	/* initialize gpio_detect */
	ret = gpio_request(hi->gpio_detect, "gpio_detect");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_detect) gpio_request\n", hi->gpio_detect);
		goto error_01;
	}

	ret = gpio_direction_input(hi->gpio_detect);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_detect) gpio_direction_input\n", hi->gpio_detect);
		goto error_02;
	}

	/* initialize gpio_jpole */
	ret = gpio_request(hi->gpio_jpole, "gpio_jpole");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_jpole) gpio_request\n", hi->gpio_jpole);
		goto error_02;
	}

	ret = gpio_direction_input(hi->gpio_jpole);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_jpole) gpio_direction_input\n", hi->gpio_jpole);
		goto error_03;
	}
	
	/* initialize gpio_key */
	ret = gpio_request(hi->gpio_key, "gpio_key");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_request\n", hi->gpio_key);
		goto error_03;
	}

	ret = gpio_direction_input(hi->gpio_key);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_key) gpio_direction_input\n", hi->gpio_key);
		goto error_04;
	}

	/* initialize gpio_mic_en */
	ret = gpio_request(hi->gpio_mic_en, "gpio_mic_en");
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_request\n", hi->gpio_mic_en);
		goto error_04;
	}

	ret = gpio_direction_output(hi->gpio_mic_en, 0);
	if (ret < 0) {
		HSD_ERR("Failed to configure gpio%d (gpio_mic_en) gpio_direction_output\n", hi->gpio_mic_en);
		goto error_05;
	}

	/* initialize irq of gpio_jpole */
	hi->irq_detect = gpio_to_irq(hi->gpio_detect);

	HSD_DBG("hi->irq_detect = %d\n", hi->irq_detect);

	if (hi->irq_detect < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_detect;
		goto error_05;
	}

//LGE_START, MYUNGWON.KIM, When Sleep IRQ Doesn't work
	ret = request_threaded_irq(hi->irq_detect, NULL, gpio_irq_handler,
					IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND, pdev->name, hi);
//LGE_END, MYUNGWON.KIM

	if (ret) {
		HSD_ERR("failed to request button irq");
		goto error_05;
	}

	ret = irq_set_irq_wake(hi->irq_detect, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set irq_detect interrupt wake\n");
		goto error_06;
	}

	/* initialize irq of gpio_key */
	hi->irq_key = gpio_to_irq(hi->gpio_key);

	HSD_DBG("hi->irq_key = %d\n", hi->irq_key);

	if (hi->irq_key < 0) {
		HSD_ERR("Failed to get interrupt number\n");
		ret = hi->irq_key;
		goto error_06;
	}

//LGE_START, MYUNGWON.KIM, When Sleep IRQ Doesn't work
	ret = request_threaded_irq(hi->irq_key, NULL, button_irq_handler,
					IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING|IRQF_NO_SUSPEND, pdev->name, hi);
//LGE_END, MYUNGWON.KIM

	if (ret) {
		HSD_ERR("failed to request button irq");
		goto error_06;
	}

	disable_irq(hi->irq_key);

	ret = irq_set_irq_wake(hi->irq_key, 1);
	if (ret < 0) {
		HSD_ERR("Failed to set irq_key interrupt wake\n");
		goto error_07;
	}

	/* initialize switch device */
	hi->sdev.name = pdata->switch_name;
	hi->sdev.print_state = lge_hsd_print_state;
	hi->sdev.print_name = lge_hsd_print_name;

	ret = switch_dev_register(&hi->sdev);
	if (ret < 0) {
		HSD_ERR("Failed to register switch device\n");
		goto error_07;
	}

	/* initialize input device */
	hi->input = input_allocate_device();
	if (!hi->input) {
		HSD_ERR("Failed to allocate input device\n");
		ret = -ENOMEM;
		goto error_08;
	}

	hi->input->name = pdata->keypad_name;

	hi->input->id.vendor    = 0x0001;
	hi->input->id.product   = 1;
	hi->input->id.version   = 1;

	/*input_set_capability(hi->input, EV_SW, SW_HEADPHONE_INSERT);*/
	set_bit(EV_SYN, hi->input->evbit);
	set_bit(EV_KEY, hi->input->evbit);
	set_bit(EV_SW, hi->input->evbit);
	set_bit(hi->key_code, hi->input->keybit);
	set_bit(SW_HEADPHONE_INSERT, hi->input->swbit);
	set_bit(SW_MICROPHONE_INSERT, hi->input->swbit);

	ret = input_register_device(hi->input);
	if (ret) {
		HSD_ERR("Failed to register input device\n");
		goto error_09;
	}
#ifdef CONFIG_LGE_AUDIO_FSA8008_MODIFY
	if (gpio_get_value_cansleep(hi->gpio_detect) == EARJACK_INSERTED) {
		queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_insert), 0); /* to detect in initialization with eacjack insertion */
	}
#else
	if (!gpio_get_value_cansleep(hi->gpio_detect))
#ifdef CONFIG_FSA8008_USE_LOCAL_WORK_QUEUE
		queue_delayed_work(local_fsa8008_workqueue, &(hi->work), 0); /* to detect in initialization with eacjack insertion */
#else
		schedule_delayed_work(&(hi->work), 0); /* to detect in initialization with eacjack insertion */
#endif
#endif

#ifdef AT_TEST_GPKD
	err = device_create_file(&pdev->dev, &dev_attr_hookkeylog);
#endif

	return ret;

error_09:
	input_free_device(hi->input);
error_08:
	switch_dev_unregister(&hi->sdev);

error_07:
	free_irq(hi->irq_key, 0);
error_06:
	free_irq(hi->irq_detect, 0);

error_05:
	gpio_free(hi->gpio_mic_en);
error_04:
	gpio_free(hi->gpio_key);
error_03:
	gpio_free(hi->gpio_jpole);
error_02:
	gpio_free(hi->gpio_detect);

error_01:
	mutex_destroy(&hi->mutex_lock);
	kfree(hi);

	return ret;
}
static int sdhci_pltfm_probe(struct platform_device *pdev)
{
	struct sdhci_host *host;
	struct sdio_dev *dev;
	struct resource *iomem;
	struct sdio_platform_cfg *hw_cfg = NULL;
	char devname[MAX_DEV_NAME_SIZE];
	int ret = 0;
	char *emmc_regulator = NULL;

	pr_debug("%s: ENTRY\n", __func__);

	BUG_ON(pdev == NULL);

	hw_cfg = (struct sdio_platform_cfg *)pdev->dev.platform_data;
	if (pdev->dev.of_node) {
		u32 val;
		const char *prop;
		if (!pdev->dev.platform_data)
			hw_cfg = kzalloc(sizeof(struct sdio_platform_cfg),
				GFP_KERNEL);

		if (!hw_cfg) {
			dev_err(&pdev->dev,
				"unable to allocate mem for private data\n");
			ret = -ENOMEM;
			goto err;
		}
		if (of_property_read_u32(pdev->dev.of_node, "id", &val)) {
			dev_err(&pdev->dev, "id read failed in %s\n", __func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->id = val;
		pdev->id = val;

		if (of_property_read_u32(pdev->dev.of_node, "data-pullup",
			&val)) {
			dev_err(&pdev->dev, "data-pullup read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->data_pullup = val;

		if (of_property_read_u32(pdev->dev.of_node, "devtype", &val)) {
			dev_err(&pdev->dev, "devtype read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->devtype = val;

		if (of_property_read_u32(pdev->dev.of_node, "flags", &val)) {
			dev_err(&pdev->dev, "flags read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->flags = val;

		if (of_property_read_u32(pdev->dev.of_node, "quirks", &val)) {
			dev_warn(&pdev->dev, "quirks not available in %s\n",
			__func__);
			val = 0;
		}

		hw_cfg->quirks = val;

		if (of_property_read_u32(pdev->dev.of_node, "quirks2", &val)) {
			dev_warn(&pdev->dev, "quirks2 not available in %s\n",
			__func__);
			val = 0;
		}

		hw_cfg->quirks2 = val;

		if (of_property_read_u32(pdev->dev.of_node, "pm_caps", &val)) {
			dev_warn(&pdev->dev, "pm_caps not available in %s\n",
			__func__);
			val = 0;
		}

		hw_cfg->pm_caps = val;

		if (of_property_read_string(pdev->dev.of_node, "peri-clk-name",
			&prop)) {
			dev_err(&pdev->dev, "peri-clk-name read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->peri_clk_name = (char *)prop;

		if (of_property_read_string(pdev->dev.of_node, "ahb-clk-name",
			&prop)) {
			dev_err(&pdev->dev, "ahb-clk-name read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->ahb_clk_name = (char *)prop;

		if (of_property_read_string(pdev->dev.of_node, "sleep-clk-name",
			&prop)) {
			dev_err(&pdev->dev, "sleep-clk-name read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->sleep_clk_name = (char *)prop;

		if (of_property_read_u32(pdev->dev.of_node, "peri-clk-rate",
			&val)) {
			dev_err(&pdev->dev, "peri-clk-rate read failed in %s\n",
			__func__);
			goto err_free_priv_data_mem;
		}

		hw_cfg->peri_clk_rate = val;

		if (hw_cfg->devtype == SDIO_DEV_TYPE_SDMMC) {
			if (of_property_read_string(pdev->dev.of_node,
				"vddo-regulator-name", &prop)) {
				dev_err(&pdev->dev, "vddo-regulator-name read "\
				"failed in %s\n", __func__);
				goto err_free_priv_data_mem;
			}

			hw_cfg->vddo_regulator_name = (char *)prop;

			if (of_property_read_string(pdev->dev.of_node,
				"vddsdxc-regulator-name", &prop)) {
				dev_err(&pdev->dev, "vddsdxc-regulator-name"\
				"read failed in %s\n", __func__);
				goto err_free_priv_data_mem;
			}

			hw_cfg->vddsdxc_regulator_name = (char *)prop;


			if (of_property_read_u32(pdev->dev.of_node,
				"cd-gpio", &val)) {
				dev_err(&pdev->dev, "cd-gpio read failed in %s\n",
				__func__);
				goto err_free_priv_data_mem;
			}

			hw_cfg->cd_gpio = val;
		}

		else if (hw_cfg->devtype == SDIO_DEV_TYPE_EMMC) {

			if (of_property_read_u32(pdev->dev.of_node,
				"is-8bit", &val)) {
				dev_err(&pdev->dev, "is-8bit read failed in %s\n",
				__func__);
				goto err_free_priv_data_mem;
			}

			hw_cfg->is_8bit = val;
			if (!(of_property_read_string(pdev->dev.of_node,
					"vddsdmmc-regulator-name", &prop)))
				emmc_regulator = (char *)prop;
		}

		pdev->dev.platform_data = hw_cfg;
	}
	if (!hw_cfg) {
			dev_err(&pdev->dev, "hw_cfg is NULL\n");
			ret = -ENOMEM;
			goto err;
	}

	if (hw_cfg->devtype >= SDIO_DEV_TYPE_MAX) {
		dev_err(&pdev->dev, "unknown device type\n");
		ret = -EFAULT;
		goto err;
	}
	pr_debug("%s: GET PLATFORM RESOURCES\n", __func__);

	iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!iomem) {
		ret = -ENOMEM;
		goto err;
	}

	/* Some PCI-based MFD need the parent here */
	if (pdev->dev.parent != &platform_bus)
		host =
		    sdhci_alloc_host(pdev->dev.parent, sizeof(struct sdio_dev));
	else
		host = sdhci_alloc_host(&pdev->dev, sizeof(struct sdio_dev));
	if (IS_ERR(host)) {
		ret = PTR_ERR(host);
		goto err;
	}

	pr_debug("%s: ALLOC HOST\n", __func__);

	host->hw_name = "bcm_kona_sd";
	host->ops = &sdhci_pltfm_ops;
	host->irq = platform_get_irq(pdev, 0);
	host->quirks = SDHCI_QUIRK_NO_CARD_NO_RESET
	    | SDHCI_QUIRK_BROKEN_TIMEOUT_VAL
	    | SDHCI_QUIRK_32BIT_DMA_ADDR
	    | SDHCI_QUIRK_32BIT_DMA_SIZE | SDHCI_QUIRK_32BIT_ADMA_SIZE;


#ifndef CONFIG_SUPPORT_UHS_CARD
	if(hw_cfg->devtype == SDIO_DEV_TYPE_SDMMC)
		hw_cfg->quirks2 = SDHCI_QUIRK2_HOST_DISABLE_UHS;
	if(hw_cfg->devtype == SDIO_DEV_TYPE_WIFI)
		hw_cfg->quirks2 = SDHCI_QUIRK2_HOST_DISABLE_UHS;
#endif

#ifdef CONFIG_MACH_RHEA_DALTON2_EB30
        host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK;
#endif
	host->quirks |= hw_cfg->quirks;
	host->quirks2 |= hw_cfg->quirks2;

        pr_debug("%s: GET IRQ\n", __func__);

	if (hw_cfg->flags & KONA_SDIO_FLAGS_DEVICE_NON_REMOVABLE)
		host->mmc->caps |= MMC_CAP_NONREMOVABLE;

	if (!request_mem_region(iomem->start, resource_size(iomem),
				mmc_hostname(host->mmc))) {
		dev_err(&pdev->dev, "cannot request region\n");
		ret = -EBUSY;
		goto err_free_host;
	}

	host->ioaddr = ioremap(iomem->start, resource_size(iomem));
	if (!host->ioaddr) {
		dev_err(&pdev->dev, "failed to remap registers\n");
		ret = -ENOMEM;
		goto err_free_mem_region;
	}

	pr_debug("%s: MEM and IO REGION OKAY\n", __func__);

	dev = sdhci_priv(host);
	dev->dev = &pdev->dev;
	dev->host = host;
	dev->devtype = hw_cfg->devtype;
	dev->cd_gpio = hw_cfg->cd_gpio;
	host->mmc->parent = dev->dev;
	if (dev->devtype == SDIO_DEV_TYPE_WIFI)
		dev->wifi_gpio = &hw_cfg->wifi_gpio;
	if (dev->devtype == SDIO_DEV_TYPE_EMMC && emmc_regulator) {
		dev->vdd_sdxc_regulator = regulator_get(NULL, emmc_regulator);
		if (IS_ERR(dev->vdd_sdxc_regulator)) {
			dev->vdd_sdxc_regulator = NULL;
		}
	}

	if (dev->devtype == SDIO_DEV_TYPE_EMMC)
		host->detect_delay = 0;
	else
		host->detect_delay = 200;

	pr_debug("%s: DEV TYPE %x\n", __func__, dev->devtype);

	gDevs[dev->devtype] = dev;

	platform_set_drvdata(pdev, dev);

	snprintf(devname, sizeof(devname), "%s%d", DEV_NAME, pdev->id);

	/* enable clocks */
#ifdef CONFIG_MACH_BCM2850_FPGA
	if (clock) {		/* clock override */
		dev->clk_hz = clock;
	} else {
		dev->clk_hz = gClock[dev->devtype];
	}
#elif defined(CONFIG_MACH_BCM_FPGA)
	dev->clk_hz = hw_cfg->peri_clk_rate;
#else
	/* peripheral clock */
	dev->peri_clk = clk_get(&pdev->dev, hw_cfg->peri_clk_name);
	if (IS_ERR_OR_NULL(dev->peri_clk)) {
		ret = -EINVAL;
		goto err_unset_pltfm;
	}
	ret = clk_set_rate(dev->peri_clk, hw_cfg->peri_clk_rate);
	if (ret)
		goto err_peri_clk_put;

	/* sleep clock */
	dev->sleep_clk = clk_get(&pdev->dev, hw_cfg->sleep_clk_name);
	if (IS_ERR_OR_NULL(dev->sleep_clk)) {
		ret = -EINVAL;
		goto err_peri_clk_put;
	}

	ret = clk_enable(dev->sleep_clk);
	if (ret) {
		dev_err(&pdev->dev, "failed to enable sleep clock for %s\n",
			devname);
		goto err_sleep_clk_put;
	}

	ret = sdhci_pltfm_clk_enable(dev, 1);
	if (ret) {
		dev_err(&pdev->dev, "failed to initialize core clock for %s\n",
			devname);
		goto err_sleep_clk_disable;
	}

	dev->clk_hz = clk_get_rate(dev->peri_clk);
#endif

	dev->suspended = 0;

	if (hw_cfg->vddo_regulator_name) {
		ret =
		    sdhci_pltfm_regulator_init(dev,
					       hw_cfg->vddo_regulator_name);
#ifndef BCM_REGULATOR_SKIP_QUIRK
		if (ret < 0)
			goto err_term_clk;
#endif
	}

	if (hw_cfg->vddsdxc_regulator_name &&
			dev->devtype == SDIO_DEV_TYPE_SDMMC) {
		ret =
		    sdhci_pltfm_regulator_sdxc_init(dev,
					       hw_cfg->vddsdxc_regulator_name);
#ifndef BCM_REGULATOR_SKIP_QUIRK
		if (ret < 0)
			goto err_term_clk;
#endif
	}

	if (sd_detection_cmd_dev == NULL){
	sd_detection_cmd_dev =
		device_create(sec_class, NULL, 0,
				NULL, "sdcard");
	if (IS_ERR(sd_detection_cmd_dev))
		pr_err("Fail to create sysfs dev\n");

	if (device_create_file(sd_detection_cmd_dev,
				&dev_attr_status) < 0)
		pr_err("Fail to create sysfs file\n");
	}

	mutex_init(&dev->regulator_lock);
	kona_sdio_regulator_power(dev, 1);

	ret = bcm_kona_sd_reset(dev);
	if (ret)
		goto err_term_clk;

	ret = bcm_kona_sd_init(dev);
	if (ret)
		goto err_reset;

	if (hw_cfg->is_8bit)
		host->mmc->caps |= MMC_CAP_8_BIT_DATA;

	/* Note that sdhci_add_host calls --> mmc_add_host, which in turn
	 * checks for the flag MMC_PM_IGNORE_PM_NOTIFY before registering a PM
	 * notifier for the specific instance of SDIO host controller. For
	 * WiFi case, we don't want to get notified, becuase then from there
	 * mmc_power_off is called which will reset the Host registers that
	 * needs to be re-programmed by starting SDIO handsake again. We want
	 * to prevent this in case of WiFi. So enable MMC_PM_IGNORE_PM_NOTIFY
	 * flag, so that notifier never gets registered.
	 */
	if (dev->devtype == SDIO_DEV_TYPE_WIFI) {
		/* The Wireless LAN drivers call the API sdio_get_host_pm_caps
		 * to know the PM capabilities of the driver, which would
		 * return pm_caps. While the internal code decides based on
		 * pm_flags, the pm_caps also should reflect the same.
		 */
		host->mmc->pm_caps =
		    MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY;
		host->mmc->pm_flags =
		    MMC_PM_KEEP_POWER | MMC_PM_IGNORE_PM_NOTIFY;
	}

	host->mmc->pm_caps |= hw_cfg->pm_caps;

#if !defined(CONFIG_MACH_BCM_FPGA_E)
	/* Enable 1.8V DDR operation for e.MMC */
	if (dev->devtype == SDIO_DEV_TYPE_EMMC)
		host->mmc->caps |= MMC_CAP_1_8V_DDR;
#endif

	/* Don't issue SLEEP command to e.MMC device */
	if (dev->devtype == SDIO_DEV_TYPE_EMMC)
		host->mmc->caps2 |= MMC_CAP2_NO_SLEEP_CMD;

	/*
	 * This has to be done before sdhci_add_host.
	 * As soon as we add the host, request
	 * starts. If we dont enable this here, the
	 * runtime get and put of sdhci will fallback to
	 * clk_enable and clk_disable which will conflict
	 * with the PM runtime when it gets enabled just
	 * after sdhci_add_host. Now with this, the RPM
	 * calls will fail until RPM is enabled, but things
	 * will work well, as we have clocks enabled till the
	 * probe ends.
	 */

	dev->runtime_pm_enabled = 1;

	ret = sdhci_add_host(host);
	if (ret)
		goto err_reset;

	ret = device_create_file(&pdev->dev, &dev_attr_card_ctrl);
	if (ret)
		goto err_rm_host;

	/* Should be done only after sdhci_add_host */
	sdhci_pltfm_runtime_pm_init(dev->dev);

	if (dev->devtype == SDIO_DEV_TYPE_SDMMC) {
		/* support SD card detect interrupts for insert/removal */
		host->mmc->card_detect_cap = true;
	}

	/* if device is eMMC, emulate card insert right here */
	if (dev->devtype == SDIO_DEV_TYPE_EMMC) {
		ret = bcm_kona_sd_card_emulate(dev, 1);
		if (ret) {
			dev_err(&pdev->dev,
				"unable to emulate card insertion\n");
			goto err_rm_sysfs;
		}
		pr_info("%s: card insert emulated!\n", devname);
	} else if (dev->devtype == SDIO_DEV_TYPE_SDMMC && dev->cd_gpio >= 0) {

		dev->cd_int_wake_lock_name = kasprintf(GFP_KERNEL,
				"%s_cd_int", devname);

		if (!dev->cd_int_wake_lock_name) {
			dev_err(&pdev->dev,
				"error allocating mem for wake_lock_name\n");
			goto err_rm_sysfs;
		}

		wake_lock_init(&dev->cd_int_wake_lock, WAKE_LOCK_SUSPEND,
				dev->cd_int_wake_lock_name);


		ret = gpio_request(dev->cd_gpio, "sdio cd");

		if (ret < 0) {
			dev_err(&pdev->dev, "Unable to request GPIO pin %d\n",
				dev->cd_gpio);
			goto err_rm_sysfs;
		}
		gpio_direction_input(dev->cd_gpio);

		ret = request_threaded_irq(gpio_to_irq(dev->cd_gpio),
					   cd_irq_handler,
					   sdhci_pltfm_cd_interrupt,
					   IRQF_TRIGGER_FALLING |
					   IRQF_TRIGGER_RISING  |
					   IRQF_NO_SUSPEND, "sdio cd", dev);
		if (ret) {
			dev_err(&pdev->dev,
				"Unable to request card detection irq=%d"
				" for gpio=%d\n",
				gpio_to_irq(dev->cd_gpio), dev->cd_gpio);
			goto err_free_cd_gpio;
		}

		/* Set debounce for SD Card detect to maximum value (128ms)
		 *
		 * NOTE-1: If gpio_set_debounce() returns error we still
		 * continue with the default debounce value set. Another reason
		 * for doing this is that on rhea-ray boards the SD Detect GPIO
		 * is on GPIO Expander and gpio_set_debounce() will return error
		 * and if we return error from here, then probe() would fail and
		 * SD detection would always fail.
		 *
		 * NOTE-2: We also give a msleep() of the "debounce" time here
		 * so that we give enough time for the debounce to stabilize
		 * before we read the gpio value in gpio_get_value_cansleep().
		 */
		ret =
		    gpio_set_debounce(dev->cd_gpio,
				      (SD_DETECT_GPIO_DEBOUNCE_128MS * 1000));
		if (ret < 0) {
			dev_err(&pdev->dev, "%s: gpio set debounce failed."
				"default debounce value assumed\n", __func__);
		}

		/* Sleep for 128ms to allow debounce to stabilize */
		msleep(SD_DETECT_GPIO_DEBOUNCE_128MS);

		/*
		 * Since the card detection GPIO interrupt is configured to be
		 * edge sensitive, check the initial GPIO value here, emulate
		 * only if the card is present
		 */
		if (gpio_get_value_cansleep(dev->cd_gpio) == 0)
			bcm_kona_sd_card_emulate(dev, 1);
		else
			/* If card is not present disable the regulator */
			kona_sdio_regulator_power(dev, 0);
	}

	/* Force insertion interrupt, in case of no card detect registered.
	 */
	if (dev->cd_gpio < 0)
		bcm_kona_sd_card_emulate(dev, 1);
#ifdef CONFIG_BRCM_UNIFIED_DHD_SUPPORT
	if ((dev->devtype == SDIO_DEV_TYPE_WIFI) &&
	    (hw_cfg->register_status_notify != NULL)) {
		hw_cfg->register_status_notify(kona_sdio_status_notify_cb,
					       host, host->mmc);
	}
	pr_debug("%s: CALL BACK IS REGISTERED\n", __func__);

#endif

	atomic_set(&dev->initialized, 1);
	sdhci_pltfm_clk_enable(dev, 0);

	pr_info("%s: initialized properly\n", devname);

	return 0;

err_free_cd_gpio:
	if (dev->devtype == SDIO_DEV_TYPE_SDMMC && dev->cd_gpio >= 0)
		gpio_free(dev->cd_gpio);

err_rm_sysfs:
	device_remove_file(&pdev->dev, &dev_attr_card_ctrl);

err_rm_host:
	sdhci_remove_host(host, 0);

err_reset:
	bcm_kona_sd_reset(dev);

err_term_clk:
	sdhci_pltfm_clk_enable(dev, 0);

#if !defined(CONFIG_MACH_BCM2850_FPGA) && !defined(CONFIG_MACH_BCM_FPGA)
err_sleep_clk_disable:
	clk_disable(dev->sleep_clk);

err_sleep_clk_put:
	clk_put(dev->sleep_clk);

err_peri_clk_put:
	clk_put(dev->peri_clk);

err_unset_pltfm:
	platform_set_drvdata(pdev, NULL);
	iounmap(host->ioaddr);
#endif

err_free_mem_region:
	release_mem_region(iomem->start, resource_size(iomem));

err_free_host:
	sdhci_free_host(host);

err_free_priv_data_mem:
	if (pdev->dev.of_node) {
		ret = -EFAULT;
		kfree(hw_cfg);
	}
err:
	pr_err("Probing of sdhci-pltfm %d failed: %d\n", pdev->id,
	       ret);
	return ret;
}
示例#7
0
static void insert_headset(struct work_struct *work)
{
	struct delayed_work *dwork = container_of(work, struct delayed_work, work);
	struct hsd_info *hi = container_of(dwork, struct hsd_info, work_for_insert);

	int earjack_type;

	int value = gpio_get_value_cansleep(hi->gpio_detect);

	if(value != EARJACK_INSERTED) {
		HSD_ERR("insert_headset but actually Fake inserted state!!\n");
		return;
	}
	else {
#ifdef HEADSET_REMOVE_ERROR
		insert_state_check = 1;
#endif
//		mutex_lock(&hi->mutex_lock);
//		switch_set_state(&hi->sdev, LGE_HEADSET);
//		mutex_unlock(&hi->mutex_lock);
	}

	HSD_DBG("insert_headset");

	if (hi->set_headset_mic_bias)
		hi->set_headset_mic_bias(TRUE);

	gpio_set_value_cansleep(hi->gpio_mic_en, 1);

	msleep(hi->latency_for_detection); // 75 -> 10 ms

	earjack_type = gpio_get_value_cansleep(hi->gpio_jpole);

	if (earjack_type == EARJACK_TYPE_3_POLE) {
		HSD_DBG("3 polarity earjack");

		if (hi->set_headset_mic_bias)
			hi->set_headset_mic_bias(FALSE);

		atomic_set(&hi->is_3_pole_or_not, 1);

		mutex_lock(&hi->mutex_lock);
		switch_set_state(&hi->sdev, LGE_HEADSET_NO_MIC);
		mutex_unlock(&hi->mutex_lock);

		input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1);
		input_sync(hi->input);
	} else {
		HSD_DBG("4 polarity earjack");

		atomic_set(&hi->is_3_pole_or_not, 0);

		cancel_delayed_work_sync(&(hi->work_for_key_det_enable));
		queue_delayed_work(local_fsa8008_workqueue, &(hi->work_for_key_det_enable), FSA8008_KEY_EN_DELAY_MS );


		mutex_lock(&hi->mutex_lock);
		switch_set_state(&hi->sdev, LGE_HEADSET);
		mutex_unlock(&hi->mutex_lock);

		input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1);
		input_sync(hi->input); // 2012-07-01, [email protected] - to prevent a lost uevent of earjack inserted
		input_report_switch(hi->input, SW_MICROPHONE_INSERT, 1);
		input_sync(hi->input);
	}
#ifdef HEADSET_REMOVE_ERROR
	insert_state_check = 0;
#endif

}
示例#8
0
static void mipi_renesas_set_backlight(struct msm_fb_data_type *mfd)
{
#ifdef SKY_LCD_SINGLE_WIRE_LB_CON
	int cnt, bl_level;	
	unsigned long flags;

	PRINT("mipi_renesas_set_backlight bl_level = %d \n", mfd->bl_level);
#ifdef CONFIG_F_SKYDISP_SILENT_BOOT
    if(is_silent_boot_mode_n_bl_off == 1) {
        printk(KERN_ERR"DONOT set backlight because this time is silentboot mode.\n");
        return;
    }
#endif

	if (prev_bl_level != mfd->bl_level) {
		bl_level=mfd->bl_level;
		if (bl_level == 0) {
			gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_LOW_VALUE);
			udelay(300);      // Disable hold time
			gpio_set_value_cansleep(gpio_lcd_bl_en, GPIO_HIGH_VALUE);		
			mdelay(5);			
			first_enable  = 0;
		} else {
			if (prev_bl_level == 0) {
				mdelay(100); 
				gpio_set_value_cansleep(gpio_lcd_bl_en, GPIO_HIGH_VALUE);
				mdelay(5); 

				gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_HIGH_VALUE);
				if (first_enable == 0) {
					first_enable = 1;
					local_save_flags(flags);
					local_irq_disable();
					udelay(10);	// T_EN
					mdelay(3);	// T_SS
					local_irq_restore(flags);
				} else {
					udelay(300);      // Turn on time
				}
			}

			if (prev_bl_level < bl_level) {
				cnt = LCD_BL_MAX - bl_level;
				cnt += prev_bl_level;
			} else {
				cnt = prev_bl_level - bl_level;
			}		

			while (cnt) {
				local_save_flags(flags);
				local_irq_disable();
				gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_LOW_VALUE);
				udelay(3);//DELAY_3NS();//udelay(3);      // Turn off time
				gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_HIGH_VALUE);
			    local_irq_restore(flags);
				udelay(10);      // Turn on time
				cnt--;
			}
		}
			
		prev_bl_level = bl_level;
		
	}
#else	//SKY_LCD_SINGLE_WIRE_LB_CON
	int bl_level;

	PRINT("mipi_renesas_set_backlight prev_bl_level=%d, bl_level=%d\n", prev_bl_level, mfd->bl_level);

#ifdef CONFIG_F_SKYDISP_SILENT_BOOT
		if(is_silent_boot_mode_n_bl_off == 1) {
			printk(KERN_ERR"DONOT set backlight because this time is silentboot mode.\n");
			return;
		}
#endif

#ifdef FEATURE_RENESAS_BL_CTRL_CHG 
		bl_level=mfd->bl_level;
		cabc_data_val[2] = bl_table[bl_level];

		//PRINT("mipi_renesas_set_backlight cabcData[1] =%d  cabc_data_val[2] = %d\n",cabc_data_val[1],cabc_data_val[2]); 
		if (bl_level == 0) {
			if(gpio_get_value_cansleep(gpio_lcd_bl_en)){
				gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_LOW_VALUE);
				gpio_set_value_cansleep(gpio_lcd_bl_en, GPIO_LOW_VALUE);	
			}
		} else {
			if(!gpio_get_value_cansleep(gpio_lcd_bl_en)){
				gpio_set_value_cansleep(gpio_lcd_bl_en, GPIO_HIGH_VALUE);
				gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_HIGH_VALUE);			
			}

			mutex_lock(&renesas_state.lcd_mutex);
			mipi_set_tx_power_mode(0);

#ifdef FEATURE_RENESAS_CABC_BUG_FIX
				mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_cabc_bugfix_NOP_set_cmds,
					ARRAY_SIZE(renesas_cabc_bugfix_NOP_set_cmds));
#endif			
			mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_cabc_bl_set_cmds,
					ARRAY_SIZE(renesas_cabc_bl_set_cmds));
			mipi_set_tx_power_mode(1);
			mutex_unlock(&renesas_state.lcd_mutex);
		}
#else
	if (prev_bl_level != mfd->bl_level) {
		bl_level=mfd->bl_level;
		cabc_data_val[2] = bl_table[bl_level];

		//PRINT("mipi_renesas_set_backlight cabcData[1] =%d  cabc_data_val[2] = %d\n",cabc_data_val[1],cabc_data_val[2]); 
		if (bl_level == 0) {
			gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_LOW_VALUE);
			udelay(300);	  // Disable hold time
			gpio_set_value_cansleep(gpio_lcd_bl_en, GPIO_LOW_VALUE);		
			mdelay(5);			
			first_enable  = 0;
		} else {
			if (first_enable == 0) {
				gpio_set_value_cansleep(gpio_lcd_bl_en, GPIO_HIGH_VALUE);
				gpio_set_value_cansleep(gpio_lcd_bl_ctl, GPIO_HIGH_VALUE);			
				first_enable  = 1;
			}

			mutex_lock(&renesas_state.lcd_mutex);
			mipi_set_tx_power_mode(0);

#ifdef FEATURE_RENESAS_CABC_BUG_FIX
			if(prev_bl_level == 0)	
			{
				mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_cabc_bugfix_NOP_set_cmds,
					ARRAY_SIZE(renesas_cabc_bugfix_NOP_set_cmds));
			}
#endif			
			mipi_dsi_cmds_tx(&renesas_tx_buf, renesas_cabc_bl_set_cmds,
					ARRAY_SIZE(renesas_cabc_bl_set_cmds));
			mipi_set_tx_power_mode(1);
			mutex_unlock(&renesas_state.lcd_mutex);
		}

		prev_bl_level = mfd->bl_level;
	}
#endif	// FEATURE_RENESAS_BL_CTRL_CHG	
#endif	//SKY_LCD_SINGLE_WIRE_LB_CON
}
static bool row_asserted(const struct matrix_keypad_platform_data *pdata,
			 int row)
{
	return gpio_get_value_cansleep(pdata->row_gpios[row]) ?
			!pdata->active_low : pdata->active_low;
}
示例#10
0
static void gpio_keys_report_event(struct gpio_button_data *bdata)
{
	const struct gpio_keys_button *button = bdata->button;
	struct input_dev *input = bdata->input;
	unsigned int type = button->type ?: EV_KEY;
	struct irq_desc *desc = irq_to_desc(gpio_to_irq(button->gpio));
	int state = (gpio_get_value_cansleep(button->gpio) ? 1 : 0) ^ button->active_low;

#ifdef CONFIG_FAST_BOOT
		/*Fake pwr off control*/
		if (fake_shut_down || fake_pressed) {
			if (button->code == KEY_POWER) {
				if (!!state) {
					printk(KERN_DEBUG"[Keys] start fake check\n");
					fake_pressed = true;
					if (!wake_lock_active(&fake_lock))
						wake_lock(&fake_lock);
					mod_timer(&fake_timer,
						jiffies + msecs_to_jiffies(500));
				} else {
					printk(KERN_DEBUG"[Keys] end fake checkPwr 0\n");
					fake_pressed = false;
					if (wake_lock_active(&fake_lock))
						wake_unlock(&fake_lock);
				}
			}
			bdata->wakeup = false;
			return ;
		}
#endif

	if (type == EV_ABS) {
		if (state) {
			input_event(input, type, button->code, button->value);
			input_sync(input);
		}
	} else {
		int report_state;
		static int prev_state;

		if (bdata->wakeup && !state) {
			input_event(input, type, button->code, !state);
			input_sync(input);
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
			printk(KERN_DEBUG"keys:f code %d, state %d\n",
				button->code, !state);
#else
			if (button->code == KEY_POWER)
				printk(KERN_DEBUG "keys:f PWR %d\n", !state);
#endif
		}

		bdata->key_state = !!state;
		bdata->wakeup = false;

		report_state = irqd_is_wakeup_set(&desc->irq_data) ? 1 : !!state;
#if !defined(CONFIG_SAMSUNG_PRODUCT_SHIP)
		printk(KERN_DEBUG"keys:code %d, state %d\n",
			button->code, report_state);
#endif
		input_event(input, type, button->code, report_state);
		input_sync(input);

		if (button->code == KEY_POWER && prev_state != report_state) {
			printk(KERN_DEBUG "keys:PWR %d\n", report_state);
			prev_state = report_state;
		}

#ifdef KEY_BOOSTER
		if (button->code == KEY_HOMEPAGE)
			gpio_key_set_dvfs_lock(bdata, !!state);
#endif
#ifdef CONFIG_INPUT_BOOSTER
		if (button->code == KEY_HOMEPAGE)
			INPUT_BOOSTER_SEND_EVENT(KEY_HOMEPAGE, !!state);
#endif
	}
}
示例#11
0
static void slimport_cable_plug_proc(struct anx7808_data *anx7808)
{
	int Pad_HW_ID = 0;

///	printk("+++++++++++++slimport_cable_plug_proc+++++++++++++++++++\n");
	if (gpio_get_value_cansleep(anx7808->pdata->gpio_cbl_det) ) {
		msleep(50);
		if (gpio_get_value_cansleep(anx7808->pdata->gpio_cbl_det) ) {
//			printk("slimport_cable_plug_proc start\n");
			if (sp_tx_pd_mode) {
///				printk("=================slimport_cable_plug_proc (1) ===============\n");
//ASUS_BSP +++ : larry lai for pad solution
				if(sp_tx_get_asus_id()) 
				{
#ifdef CONFIG_EEPROM_NUVOTON				
					Pad_HW_ID = AX_MicroP_IsMydpNewSKU();
#else
					Pad_HW_ID = -1;  // default TV mode
#endif
					if (Pad_HW_ID == 1)
					{
						printk("### [myDP] DP Pad detect ###\n");				
						sp_tx_asus_pad = 1;	
						myDP_DP_Dongle = 1;
					}
					else if (Pad_HW_ID == 0)
					{
						printk("### [myDP] HDMI Pad detect ###\n");				
						sp_tx_asus_pad = 1;
						myDP_DP_Dongle = 0;
					}
					else
					{
						if (myDP_force_pad_mode)
						{
							if (myDP_DP_Dongle)
							{
								printk("[myDP] DP Pad detect ###\n");				
								sp_tx_asus_pad = 1;	
								myDP_DP_Dongle = 1;
							}
							else
							{
								printk("[myDP] HDMI Pad detect ###\n");				
								sp_tx_asus_pad = 1;
								myDP_DP_Dongle = 0;							
							}
						}
						else
						{
							printk("### [myDP] Fail detect Pad , force TV mode ###\n");									
							sp_tx_asus_pad = 0;
							myDP_DP_Dongle = 0;											
						}
					}
				}
				else
					nv_touch_mode(4);	//ASUS_BSP Deeo : notify touch while plug out HDMI 4: AC

//ASUS_BSP --- : larry lai for pad solution

				//sp_tx_hardware_chip_enable(anx7808_client);
				sp_tx_hardware_poweron(anx7808_client);

				sp_tx_pd_mode = 0;

//ANX : (ver:20130105) diff with ANX slimport driver, comment it ??? 			
////				msleep(200);
				sp_tx_power_on(SP_TX_PWR_REG);
				sp_tx_power_on(SP_TX_PWR_TOTAL);
///				printk("=================slimport_cable_plug_proc (2) ===============\n");
//ANX : (ver:0.2)
				sp_tx_pull_down_id(TRUE);

				hdmi_rx_initialization();
///				printk("=================slimport_cable_plug_proc (3) ===============\n");
				sp_tx_initialization();
///				printk("=================slimport_cable_plug_proc (4) ===============\n");
//ASUS_BSP +++ : larry lai for pad solution
				if (!sp_tx_asus_pad)
				{
					sp_tx_vbus_poweron();
					msleep(200);
				}
				else
				{
					msleep(20);					
				}
//ASUS_BSP --- : larry lai for pad solution				
				if (!sp_tx_get_cable_type()) {
					DEV_ERR("%s:AUX ERR\n", __func__);
					sp_tx_vbus_powerdown();
//ANX : (ver:0.2)					
					sp_tx_pull_down_id(FALSE);
					sp_tx_power_down(SP_TX_PWR_REG);
					sp_tx_power_down(SP_TX_PWR_TOTAL);
//					sp_tx_hardware_chip_disable(anx7808_client);
					sp_tx_hardware_powerdown(anx7808_client);
					sp_tx_pd_mode = 1;
					sp_tx_link_config_done = 0;
					sp_tx_hw_lt_enable = 0;
					sp_tx_hw_lt_done = 0;
					sp_tx_rx_type = RX_NULL;
					sp_tx_rx_type_backup = RX_NULL;
//ANX +++: (ver:20130105) pad solution
					sp_tx_asus_pad = 0;
//ANX ---: (ver:20130105) pad solution
					sp_tx_set_sys_state(STATE_CABLE_PLUG);
					return;
				}
///				printk("=================slimport_cable_plug_proc (5) ===============\n");
				sp_tx_rx_type_backup = sp_tx_rx_type;
			}
			switch(sp_tx_rx_type) {
			case RX_HDMI:
///				printk("=================slimport_cable_plug_proc (RX_HDMI) ===============\n");
				if(sp_tx_get_hdmi_connection()){
					printk("==== (RX_HDMI) ===\n");
//ANX +++: (ver:20130105) pad solution					
					if(sp_tx_asus_pad) {
						//skip EDID read
						hdmi_rx_set_hpd(1);
						hdmi_rx_set_termination(1);
						sp_tx_set_sys_state(STATE_CONFIG_HDMI);
					} else {
						sp_tx_set_sys_state(STATE_PARSE_EDID);
					}
//ANX ---: (ver:20130105) pad solution					
					}
				break;
			case RX_DP:
				if(sp_tx_get_dp_connection())
				{
					printk("==== (RX_DP) ===\n");				
					if(sp_tx_asus_pad) {
						//skip EDID read
						hdmi_rx_set_hpd(1);
						hdmi_rx_set_termination(1);
						sp_tx_set_sys_state(STATE_CONFIG_HDMI);
					} else {				
						sp_tx_set_sys_state(STATE_PARSE_EDID);
					}
				}
				break;
			case RX_VGA:
				if(sp_tx_get_vga_connection()){
					sp_tx_send_message(MSG_CLEAR_IRQ); 
					sp_tx_set_sys_state(STATE_PARSE_EDID);
				}
				break;
			case RX_NULL:
			default:
				break;
			}
		}
	} else if (sp_tx_pd_mode == 0) {
		sp_tx_vbus_powerdown();
//ANX : (ver:0.2)		
		sp_tx_pull_down_id(FALSE);
		sp_tx_power_down(SP_TX_PWR_REG);
		sp_tx_power_down(SP_TX_PWR_TOTAL);
		sp_tx_hardware_powerdown(anx7808_client);
//		sp_tx_hardware_chip_disable(anx7808_client);
		sp_tx_pd_mode = 1;
		sp_tx_link_config_done = 0;
		sp_tx_hw_lt_enable = 0;
		sp_tx_hw_lt_done = 0;
		sp_tx_rx_type = RX_NULL;
		sp_tx_rx_type_backup = RX_NULL;
//ANX +++: (ver:20130105) pad solution		
		sp_tx_asus_pad = 0;
//ANX ---: (ver:20130105) pad solution		
		sp_tx_set_sys_state(STATE_CABLE_PLUG);
	}
}
示例#12
0
static int anx7808_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{

	struct anx7808_data *anx7808;
	struct regulator *anx7808_v10;
	int ret = 0;
	int irq=0;
	printk("##########anx7808_i2c_probe###################\n");
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) {
		DEV_ERR("%s: i2c bus does not support the anx7808\n", __func__);
		ret = -ENODEV;
		goto exit;
	}

	anx7808 = kzalloc(sizeof(struct anx7808_data), GFP_KERNEL);
	if (!anx7808) {
		DEV_ERR("%s: failed to allocate driver data\n", __func__);
		ret = -ENOMEM;
		goto exit;
	}
	
	anx7808->pdata = client->dev.platform_data;

	memcpy(&anx7808_client, &client, sizeof(client));

	mutex_init(&anx7808->lock);

	if (!anx7808->pdata) {
		ret = -EINVAL;
		goto err0;
	}

	myDPClass = class_create(THIS_MODULE, "myDP");
	if (IS_ERR(myDPClass)) {
		pr_info("myDP class_create failed %d\n", ret);
	      ret = PTR_ERR(myDPClass);
		goto err0;
	}

      myDPClass->dev_attrs = mydp_driver_attribs;

      g_myDP_pDevice  = device_create(myDPClass, NULL,
    									 MKDEV(g_myDP_devMajor, 0),  NULL,
    									 "%s", MYDP_DEVICE_NAME);
    if (IS_ERR(g_myDP_pDevice)) {
    	 pr_info("myDP class_device_create failed %s %d\n", MYDP_DEVICE_NAME, ret);
        ret = PTR_ERR(g_myDP_pDevice);
	  goto free_class;
    }

	ret = anx7808_init_gpio(anx7808);
	if (ret) {
		DEV_ERR("%s: failed to initialize gpio\n", __func__);
		goto err1;
	}

	anx7808_v10=regulator_get(NULL,"8921_l12");
	 if (IS_ERR(anx7808_v10)) {
		printk("unable to get anx7808_v10\n");
		return PTR_ERR(anx7808_v10);
	}
      ret = regulator_set_voltage(anx7808_v10, 1000000, 1000000);
	if (ret) {
		printk("%s: unable to set the voltage for regulator "
			"anx7808_v10\n", __func__);
		return ret;
	}
	regulator_enable(anx7808_v10);
	
//ASUS BSP wei lai +++
#if 1
	irq = MSM_GPIO_TO_INT(anx7808->pdata->gpio_usb_id);
	if (irq < 0) {
		printk( "%s: could not get USB_ID_DETECT IRQ resource, error=%d ", __func__, irq);		
	}
	ret = request_irq(irq, dp_usb_id_detect_handler,
		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING , "dp usb id mode", anx7808);

	if (ret < 0) {
		printk( "%s: FACTORY USB IRQ#%d request failed with error=%d ", __func__, irq, ret);				
	}
	disable_irq(irq);
#endif
//ASUS BSP wei lai ---

	INIT_DELAYED_WORK(&anx7808->work, anx7808_work_func);
//ASUS BSP wei lai +++
	INIT_DELAYED_WORK(&anx7808->carKitwork, anx7808_carKitwork_func);
//ASUS BSP wei lai ---
	anx7808->workqueue = create_singlethread_workqueue("anx7808_work");
	if (anx7808->workqueue == NULL) {
		DEV_ERR("%s: failed to create work queue\n", __func__);
		ret = -ENOMEM;
		goto err2;
	}
//ASUS BSP wei lai +++
#ifdef CONFIG_HAS_EARLYSUSPEND
	register_early_suspend( &dp7808_early_suspend_desc );
#endif
//ASUS BSP wei lai ---
	ret = anx7808_system_init();
	if (ret) {
		DEV_ERR("%s: failed to initialize anx7808\n", __func__);
		goto err2;
	}
//ASUS_BSP larry lai :for ATD test +++	
	g_myDP_init_status = 1;
//ASUS_BSP larry lai :for ATD test ---

	client->irq = gpio_to_irq(anx7808->pdata->gpio_cbl_det);
	if (client->irq < 0) {
		DEV_ERR("%s : failed to get gpio irq\n", __func__);
		goto err3;
	}

	ret = request_threaded_irq(client->irq, NULL, anx7808_cbl_det_isr,
					IRQF_TRIGGER_RISING
					| IRQF_TRIGGER_FALLING,
					"anx7808_cabel_det", anx7808);
	if (ret  < 0) {
		DEV_ERR("%s : failed to request irq\n", __func__);
		goto err3;
	}
//wei debug irq
#if 1
//	ret = set_irq_wake(client->irq, 1);
//ASUS Wei_Lai +++
	ret = irq_set_irq_wake(client->irq, 1);
//ASUS Wei_Lai ---
	if (ret  < 0) {
		pr_err("%s : Request irq for cable detect"
			"interrupt wake set fail\n", __func__);
		goto err3;
	}
#endif
//wei debug irq
#if 1
	ret = enable_irq_wake(client->irq);
	if (ret  < 0) {
		DEV_ERR("%s : Enable irq for cable detect", __func__);
		DEV_ERR("interrupt wake enable fail\n");
		goto err3;
	}
#endif	

	//enable_irq(client->irq);
//ASUS BSP wei lai +++
	enable_irq(irq);
	i2c_set_clientdata(anx7808_client,anx7808);

	printk("########## #####anx7808_i2c_probe END###################\n");
	wake_lock_init(&anx7808->slimport_lock, WAKE_LOCK_SUSPEND, "slimport_wake_lock");

	if (gpio_get_value(anx7808->pdata->gpio_cbl_det) && (g_i2c_error_count==0))  {
		msleep(10);
		if(gpio_get_value(anx7808->pdata->gpio_cbl_det)==1){
			wake_lock(&anx7808->slimport_lock);
			DEV_DBG("%s : detect cable insertion\n", __func__);
			queue_delayed_work(anx7808->workqueue, &anx7808->work, 1000);
		}
	}
	if (gpio_get_value_cansleep(anx7808 ->pdata->gpio_usb_id) ==0 ){
		if(gpio_get_value_cansleep(anx7808->pdata->gpio_cbl_det) ==0){
			g_otg_state=true;
		}
	}
	
//ASUS BSP wei lai ---
	goto exit;

err3:
	free_irq(client->irq, anx7808);
err2:
	destroy_workqueue(anx7808->workqueue);
err1:
	anx7808_free_gpio(anx7808);
free_class:
	class_destroy(myDPClass);	
err0:
	kfree(anx7808);
exit:
	return ret;
}
static int hall_ic_dock_probe(struct platform_device *pdev)
{
	struct hall_ic_dock_device *dev;
	int ret;
#ifndef CONFIG_MACH_LGE_I_BOARD_DCM
    int err;
	int state;
#endif /* CONFIG_MACH_LGE_I_BOARD_DCM */

	dev = kzalloc(sizeof(struct hall_ic_dock_device), GFP_KERNEL);
	dock_dev = dev;

	dev->sdev.name = "dock";
	dev->sdev.print_name = hall_ic_dock_print_name;

	ret = switch_dev_register(&dev->sdev);
	if (ret < 0)
		goto err_switch_dev_register;

	platform_set_drvdata(pdev, dev);

#ifndef CONFIG_MACH_LGE_I_BOARD_DCM
	INIT_DELAYED_WORK(&dev->work, hall_ic_dock_work_func);

	ret = gpio_request(GPIO_CAR_CRADLE, "carkit_detect");
	if(ret < 0)
		goto err_request_carkit_detect_gpio;

	ret = gpio_direction_input(GPIO_CAR_CRADLE);
	if (ret < 0)
		goto err_set_carkit_detect_gpio;
	
	ret = request_threaded_irq(GPIO_CAR_CRADLE_INT,NULL, hall_ic_dock_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,"hall-ic-carkit", dev);

	if (ret) {
		printk("\nHALL IC CARKIT IRQ Check-fail\n pdev->client->irq %d\n",dev->s_hall_ic_carkit_gpio);
		goto err_request_carkit_detect_irq;
	}

	err = irq_set_irq_wake(GPIO_CAR_CRADLE_INT, 1);
	if (err) {
		pr_err("hall-ic-carkit: set_irq_wake failed for gpio %d, "
				"irq %d\n", GPIO_CAR_CRADLE, GPIO_CAR_CRADLE_INT);
	}



	ret = gpio_request(GPIO_POUCH, "pouch_detect");
	if(ret < 0)
		goto err_request_carkit_detect_gpio;

	ret = gpio_direction_input(GPIO_POUCH);
	if (ret < 0)
		goto err_set_carkit_detect_gpio;

	ret = request_threaded_irq(GPIO_POUCH_INT,NULL, hall_ic_dock_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,"hall-ic-pouch", dev);

	if (ret) {
		printk("\nHALL IC CARKIT IRQ Check-fail\n pdev->client->irq %d\n",dev->s_hall_ic_carkit_gpio);
		goto err_request_carkit_detect_irq;
	}

	err = irq_set_irq_wake(GPIO_POUCH_INT, 1);
	if (err) {
		pr_err("hall-ic-carkit: set_irq_wake failed for gpio %d, "
				"irq %d\n", GPIO_POUCH, GPIO_POUCH_INT);
	}

#if 0
	dev->s_hall_ic_desk_gpio = gpio_to_irq(GPIO_DESK_IRQ);
	ret = request_irq(dev->s_hall_ic_desk_gpio, hall_ic_dock_irq_handler,
			IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING,
			"hall-ic-multikit", dev); 

	if (ret) {
		printk("\nHALL IC MULTIKIT IRQ Check-fail\n pdev->client->irq %d\n",dev->s_hall_ic_desk_gpio);
		goto err_request_multikit_detect_irq;
	}

	err = irq_set_irq_wake(dev->s_hall_ic_desk_gpio, 1);
	if (err) {
		pr_err("hall-ic-multikit: set_irq_wake failed for gpio %d, "
				"irq %d\n", GPIO_DESK_IRQ, dev->s_hall_ic_desk_gpio);
	}
#endif
#endif /* CONFIG_MACH_LGE_I_BOARD_DCM */

	ret = device_create_file(&pdev->dev, &dev_attr_report);
	if (ret) {
		printk( "hall-ic-dock_probe: device create file Fail\n");
		device_remove_file(&pdev->dev, &dev_attr_report);
		goto err_request_irq;
	}

#ifndef CONFIG_MACH_LGE_I_BOARD_DCM
#ifdef CONFIG_HAS_EARLYSUSPEND
	hall_ic_early_suspend.suspend = hall_early_suspend;
	hall_ic_early_suspend.resume = hall_late_resume;
	hall_ic_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 45;
	register_early_suspend(&hall_ic_early_suspend);
#endif

	/* check initial dock state */
	if(gpio_get_value_cansleep(GPIO_POUCH) == GPIO_POUCH_DETECT)
	{
   		printk("### pouch detect \n");
		state = DOCK_STATE_POUCH; //DOCK_STATE_DESK;
	}
	else if(gpio_get_value_cansleep(GPIO_CAR_CRADLE) ==  GPIO_CARKIT_DETECT)
	{
		printk("### carkit detect \n");
		state = DOCK_STATE_CAR;
	}
	else
	{
   		printk("### undock detect \n");	
		state = DOCK_STATE_UNDOCKED;
	}

	printk(KERN_INFO"%s:  curr:%d, \n",__func__,state);

	hall_ic_dock_report_event(state);
#endif /* CONFIG_MACH_LGE_I_BOARD_DCM */


	printk(KERN_ERR "hall_ic_dock: hall_ic_dock_probe: Done\n");
	return 0;

err_request_irq:
#ifndef CONFIG_MACH_LGE_I_BOARD_DCM
	free_irq(GPIO_CAR_CRADLE_INT, 0);
#if 0	
	free_irq(dev->s_hall_ic_desk_gpio, 0);
#endif
//err_request_multikit_detect_irq:
	free_irq(GPIO_CAR_CRADLE_INT, 0);
err_request_carkit_detect_irq:
//err_set_multikit_detect_gpio:
err_set_carkit_detect_gpio:
#if 0	
	gpio_free(GPIO_DESK_IRQ);
#endif
//err_request_multikit_detect_gpio:
	gpio_free(GPIO_CAR_CRADLE);
err_request_carkit_detect_gpio:
	switch_dev_unregister(&dev->sdev);
	kfree(dev);
#endif /* CONFIG_MACH_LGE_I_BOARD_DCM */
err_switch_dev_register:
	printk(KERN_ERR "hall_ic_dock: Failed to register driver\n");
	return ret;
}
示例#14
0
static void slimport_cable_plug_proc(struct anx7808_data *anx7808)
{
	struct anx7808_platform_data *pdata = anx7808->pdata;

	if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
		mdelay(100);
		if (gpio_get_value_cansleep(pdata->gpio_cbl_det)) {
			if (sp_tx_pd_mode) {
				sp_tx_pd_mode = 0;
#ifdef CONFIG_SLIMPORT_DYNAMIC_HPD
				slimport_set_hdmi_hpd(1);
#endif
				sp_tx_hardware_poweron();
				sp_tx_power_on(SP_TX_PWR_REG);
				sp_tx_power_on(SP_TX_PWR_TOTAL);
				hdmi_rx_initialization();
				sp_tx_initialization();
				sp_tx_vbus_poweron();
				msleep(200);
				if (!sp_tx_get_cable_type()) {
					pr_err("%s %s:AUX ERR\n",
						   LOG_TAG, __func__);
					sp_tx_vbus_powerdown();
					sp_tx_power_down(SP_TX_PWR_REG);
					sp_tx_power_down(SP_TX_PWR_TOTAL);
					sp_tx_hardware_powerdown();
					sp_tx_pd_mode = 1;
					sp_tx_link_config_done = 0;
					sp_tx_hw_lt_enable = 0;
					sp_tx_hw_lt_done = 0;
					sp_tx_rx_type = RX_NULL;
					sp_tx_rx_type_backup = RX_NULL;
					sp_tx_set_sys_state(STATE_CABLE_PLUG);
					return;
				}
				sp_tx_rx_type_backup = sp_tx_rx_type;
			}
			switch (sp_tx_rx_type) {
			case RX_HDMI:
				if (sp_tx_get_hdmi_connection())
					sp_tx_set_sys_state(STATE_PARSE_EDID);
				break;
			case RX_DP:
				if (sp_tx_get_dp_connection())
					sp_tx_set_sys_state(STATE_PARSE_EDID);
				break;
			case RX_VGA_GEN:
				if (sp_tx_get_vga_connection())
					sp_tx_set_sys_state(STATE_PARSE_EDID);
				break;
			case RX_VGA_9832:
				if (sp_tx_get_vga_connection()) {
					sp_tx_send_message(MSG_CLEAR_IRQ);
					sp_tx_set_sys_state(STATE_PARSE_EDID);
				}
				break;
			case RX_NULL:
			default:
				break;
			}
		}
	} else if (sp_tx_pd_mode == 0) {
		sp_tx_vbus_powerdown();
		sp_tx_power_down(SP_TX_PWR_REG);
		sp_tx_power_down(SP_TX_PWR_TOTAL);
		sp_tx_hardware_powerdown();
		sp_tx_pd_mode = 1;
		sp_tx_link_config_done = 0;
		sp_tx_hw_lt_enable = 0;
		sp_tx_hw_lt_done = 0;
		sp_tx_rx_type = RX_NULL;
		sp_tx_rx_type_backup = RX_NULL;
		sp_tx_set_sys_state(STATE_CABLE_PLUG);
	}
}