static void usb_headset_detect(int type)
{
    int state_h2w = 0;
    int state_usb = 0;

    HS_DBG();

    mutex_lock(&hi->mutex_lock);
    state_h2w = switch_get_state(&hi->sdev_h2w);

    switch (type) {
    case USB_NO_HEADSET:
        hi->usb_headset.type = USB_NO_HEADSET;
        hi->usb_headset.status = STATUS_DISCONNECTED;
        state_h2w &= ~MASK_USB_HEADSET;
        state_usb = GOOGLE_USB_AUDIO_UNPLUG;
        HS_LOG_TIME("Remove USB_HEADSET (state %d, %d)",
                    state_h2w, state_usb);
        break;
    case USB_AUDIO_OUT:
        hi->usb_headset.type = USB_AUDIO_OUT;
        hi->usb_headset.status = STATUS_CONNECTED_ENABLED;
        state_h2w |= BIT_USB_AUDIO_OUT;
        state_usb = GOOGLE_USB_AUDIO_ANLG;
        HS_LOG_TIME("Insert USB_AUDIO_OUT (state %d, %d)",
                    state_h2w, state_usb);
        break;
    default:
        HS_LOG("Unknown headset type");
    }

    switch_set_state(&hi->sdev_h2w, state_h2w);
    switch_set_state(&hi->sdev_usb_audio, state_usb);
    mutex_unlock(&hi->mutex_lock);
}
Example #2
0
void headset_ext_detect(int type)
{
	HS_DBG();

	switch (type) {
	case H2W_NO_HEADSET:
		/* Release Key */
	case H2W_HEADSET:
	case H2W_35MM_HEADSET:
	case H2W_REMOTE_CONTROL:
	case H2W_USB_CRADLE:
	case H2W_UART_DEBUG:
	case H2W_TVOUT:
		break;
	case USB_NO_HEADSET:
		/* Release Key */
	case USB_AUDIO_OUT:
#ifdef CONFIG_SUPPORT_USB_SPEAKER
	case USB_AUDIO_OUT_DGTL:
#endif
		usb_headset_detect(type);
		break;
	default:
		HS_LOG("Unknown headset type");
	}
}
static void headset_notifier_update(int id)
{
    if (!hi) {
        HS_LOG("HS_MGR driver is not ready");
        return;
    }

    switch (id) {
    case HEADSET_REG_HPIN_GPIO:
        break;
    case HEADSET_REG_REMOTE_ADC:
        update_mic_status(HS_DEF_MIC_DETECT_COUNT);
        break;
    case HEADSET_REG_REMOTE_KEYCODE:
    case HEADSET_REG_RPC_KEY:
        break;
    case HEADSET_REG_MIC_STATUS:
        update_mic_status(HS_DEF_MIC_DETECT_COUNT);
        break;
    case HEADSET_REG_MIC_BIAS:
    case HEADSET_REG_MIC_SELECT:
    case HEADSET_REG_KEY_INT_ENABLE:
    case HEADSET_REG_KEY_ENABLE:
    case HEADSET_REG_INDICATOR_ENABLE:
        break;
    default:
        break;
    }
}
Example #4
0
static struct file *openFile(char *path,int flag,int mode)
{
	mm_segment_t old_fs;
	old_fs = get_fs();
	set_fs(KERNEL_DS);
	fp=filp_open(path, flag, mode);
	set_fs(old_fs);
	if(IS_ERR(fp))
	   HS_LOG("File Open Error:%s",path);

	if(!fp->f_op)
	   HS_LOG("File Operation Method Error!!");

	if (fp) return fp;
	else return NULL;
}
int hs_notify_key_event(int key_code)
{
    struct button_work *work;

    HS_DBG();

    if (hi->hs_35mm_type == HEADSET_UNKNOWN_MIC ||
            hi->hs_35mm_type == HEADSET_NO_MIC ||
            hi->h2w_35mm_type == HEADSET_NO_MIC)
        update_mic_status(HS_DEF_MIC_DETECT_COUNT);
    else if (!hs_hpin_stable()) {
        HS_LOG("The HPIN is unstable, SKIP THE BUTTON EVENT.");
        return 1;
    } else {
        work = kzalloc(sizeof(struct button_work), GFP_KERNEL);
        if (!work) {
            HS_ERR("Failed to allocate button memory");
            return 1;
        }
        work->key_code = key_code;
        INIT_DELAYED_WORK(&work->key_work, button_35mm_work_func);
        queue_delayed_work(button_wq, &work->key_work,
                           HS_JIFFIES_BUTTON);
    }

    return 1;
}
static void onewire_init_work_func(struct work_struct *work)
{
    HS_LOG("Open %s", hi->pdata.onewire_tty_dev);
    fp = openFile(hi->pdata.onewire_tty_dev,O_CREAT|O_RDWR|O_NONBLOCK,0666);
    if (fp != NULL) {
        if (!fp->private_data)
            HS_LOG("No private data");
        else {
            HS_LOG("Private data exist");
            closeFile(fp);
            return;
        }
    } else
        HS_LOG("%s, openFile is NULL pointer\n", __func__);
    closeFile(fp);
}
Example #7
0
int headset_notifier_register(struct headset_notifier *notifier)
{
    if (!notifier->func) {
        HS_LOG("NULL register function");
        return 0;
    }

    switch (notifier->id) {
    case HEADSET_REG_HPIN_GPIO:
        HS_LOG("Register HPIN_GPIO notifier");
        hs_mgr_notifier.hpin_gpio = notifier->func;
        break;
    case HEADSET_REG_REMOTE_ADC:
        HS_LOG("Register REMOTE_ADC notifier");
        hs_mgr_notifier.remote_adc = notifier->func;
        break;
    case HEADSET_REG_RPC_KEY:
        HS_LOG("Register RPC_KEY notifier");
        hs_mgr_notifier.rpc_key = notifier->func;
        break;
    case HEADSET_REG_MIC_STATUS:
        HS_LOG("Register MIC_STATUS notifier");
        hs_mgr_notifier.mic_status = notifier->func;
        break;
    case HEADSET_REG_MIC_BIAS:
        HS_LOG("Register MIC_BIAS notifier");
        hs_mgr_notifier.mic_bias_enable = notifier->func;
        break;
    case HEADSET_REG_MIC_SELECT:
        HS_LOG("Register MIC_SELECT notifier");
        hs_mgr_notifier.mic_select = notifier->func;
        break;
    case HEADSET_REG_KEY_INT_ENABLE:
        HS_LOG("Register KEY_INT_ENABLE notifier");
        hs_mgr_notifier.key_int_enable = notifier->func;
        break;
    case HEADSET_REG_KEY_ENABLE:
        HS_LOG("Register KEY_ENABLE notifier");
        hs_mgr_notifier.key_enable = notifier->func;
        break;
    default:
        HS_LOG("Unknown register ID");
        return 0;
    }

    return 1;
}
static void hs_1wire_deinit(void)
{
	char all_zero = 0xaa;
	if (fp) {
		if (hi->pdata.tx_level_shift_en)
			gpio_set_value_cansleep(hi->pdata.tx_level_shift_en, 0);
		hr_msleep(20);
		writeFile(fp, &all_zero, 1); 
		HS_LOG("Write 0xaa to unblock");
		hr_msleep(10);
		HS_LOG("close file");
		closeFile(fp);
		fp = NULL;
		if (hi->pdata.tx_level_shift_en)
			gpio_set_value_cansleep(hi->pdata.tx_level_shift_en, 1);
	}
}
Example #9
0
void headset_button_event(int is_press, int type)
{
	HS_DBG();

	if (!hs_hpin_stable()) {
		HS_LOG("The HPIN is unstable, SKIP THE BUTTON EVENT.");
		return;
	}
	if (!get_mic_state()) {
		HS_LOG("IGNORE key %d (Not support MIC)", type);
		return;
	}
	if (!is_press)
		button_released(type);
	else if (!atomic_read(&hi->btn_state))
		button_pressed(type);
}
static void irq_init_work_func(struct work_struct *work)
{
	HS_DBG();

	if (hi->pdata.hpin_gpio) {
		HS_LOG("Enable detect IRQ");
		set_irq_type(hi->hpin_irq, IRQF_TRIGGER_LOW);
		enable_irq(hi->hpin_irq);
	}

	if (hi->pdata.key_gpio) {
		HS_LOG("Enable button IRQ");
		hi->key_irq_type = IRQF_TRIGGER_LOW;
		set_irq_type(hi->key_irq, hi->key_irq_type);
		enable_irq(hi->key_irq);
	}
}
static int headset_1wire_parse_dt(struct htc_hs_1wire_data *wire)
{
    int i,ret = 0;
    const char *ttyname;
    u32 remoteadc[6] = {0};
    struct device_node *dt = wire->dev->of_node;
    HS_LOG("%s", __func__);

    wire->pdata->tx_level_shift_en = of_get_named_gpio(dt, "hs_1wire,tx_level_shift_en", 0);
    if (gpio_is_valid(wire->pdata->tx_level_shift_en)) {
        HS_LOG("tx_lv_en:%d", wire->pdata->tx_level_shift_en);
    } else
        HS_LOG("tx_lv_en parser err");

    ret = of_property_read_u32_array(dt, "hs_1wire,one_wire_remote", remoteadc, 6);
    if (ret < 0) {
        HS_LOG("remote parser failure");
    } else {
        for (i = 0; i < ARRAY_SIZE(remoteadc); i++) {
            wire->pdata->one_wire_remote[i] = (char)remoteadc[i];
        }
        HS_LOG("remote: %#x %#x %#x", remoteadc[0], remoteadc[1],
               remoteadc[2]);
    }

    ret = of_property_read_string(dt, "hs_1wire,onewire_tty_dev", &ttyname);
    if (ret < 0) {
        HS_LOG("tty_dev string parser failue");
    } else {
        snprintf(wire->pdata->onewire_tty_dev, 15, "/dev/%s", ttyname);
        HS_LOG("tty=%s", wire->pdata->onewire_tty_dev);
    }

    return 0;
}
static int hs_read_aid(void)
{
	char in_buf[10];
	int read_count, i;
		read_count = readFile(fp, in_buf, 10);
		HS_LOG("[1wire]read_count = %d", read_count);
		if (read_count > 0) {
			for (i = 0; i < read_count; i++) {
				HS_LOG("[1wire]in_buf[%d] = 0x%x", i, in_buf[i]);
				if ((in_buf[i] & 0xF0) == 0x80 && in_buf[i] > 0x80) {
					hi->aid = in_buf[i];
					return 0;
				}
			}
		}
	return -1;

}
static int hs_gpio_request_irq(unsigned int gpio, unsigned int *irq,
			       irq_handler_t handler, unsigned long flags,
			       const char *name, unsigned int wake)
{
	int ret = 0;

	HS_DBG();

	ret = gpio_request(gpio, name);
	if (ret < 0)
		return ret;

	ret = gpio_direction_input(gpio);
	if (ret < 0) {
		gpio_free(gpio);
		return ret;
	}

	if (!(*irq)) {
		ret = gpio_to_irq(gpio);
		if (ret < 0) {
			gpio_free(gpio);
			return ret;
		}
		HS_LOG("gpio_to_irq ret = %d", ret);
		*irq = (unsigned int) ret;
	}

	HS_LOG("[HS] irq=%d", *irq);
	ret = request_irq(*irq, handler, flags, name, NULL);
	if (ret < 0) {
		gpio_free(gpio);
		return ret;
	}

	ret = set_irq_wake(*irq, wake);
	if (ret < 0) {
		free_irq(*irq, 0);
		gpio_free(gpio);
		return ret;
	}

	return 1;
}
static void hs_gpio_uart_set(int value)
{
	value = !!value;

	if (value != headset_uart_enable) {
		headset_uart_enable = value;
		HS_LOG("%s headset uart", value? "enable": "disable");
		gpio_set_value(hi->pdata.uart_gpio, value);
	}
}
static struct file *openFile(char *path,int flag,int mode)
{
	mm_segment_t old_fs;
	mutex_lock(&hi->mutex_lock);
	old_fs = get_fs();
	set_fs(KERNEL_DS);
	HS_LOG("Open: fp count = %d", ++fp_count);
	fp=filp_open(path, flag, mode);
	set_fs(old_fs);
	if (!fp)
		return NULL;
	if(IS_ERR(fp))
	   HS_LOG("File Open Error:%s",path);

	if(!fp->f_op)
	   HS_LOG("File Operation Method Error!!");

	return fp;
}
static int hs_1wire_report_type(char **string)
{
	const int type_num = 3; /*How many 1-wire accessories supported*/
	char *hs_type[] = {
		"headset_beats_20",
		"headset_mic_midtier",
		"headset_beats_solo_20",
	};
	hi->aid &= 0x7f;
	HS_LOG("[1wire]AID = 0x%x", hi->aid);
	if (hi->aid > type_num || hi->aid < 1) {
		*string = "1wire_unknown";
		return 14;
	}else {
		*string = hs_type[hi->aid - 1];
		HS_LOG("Report %s type, size %d", *string, sizeof(hs_type[hi->aid -1]));
		return sizeof(hs_type[hi->aid -1]);
	}
}
int closeFile(struct file *fp)
{
	mm_segment_t old_fs;
	old_fs = get_fs();
	set_fs(KERNEL_DS);
	HS_LOG("Close: fp count = %d", --fp_count);
	filp_close(fp,NULL);
	set_fs(old_fs);
	return 0;
}
static int hs_8x60_remote_adc(int *adc)
{
	int ret = 0;

	HS_DBG();

	ret = pm8058_htc_config_mpp_and_adc_read(adc, 1, CHANNEL_ADC_HDSET,
						 hi->pdata.adc_mpp,
						 hi->pdata.adc_amux);
	if (ret) {
		*adc = -1;
		HS_LOG("Failed to read remote ADC");
		return 0;
	}

	HS_LOG("Remote ADC %d (0x%X)", *adc, *adc);

	return 1;
}
static int hs_1wire_report_type(char **string)
{
    const int type_num = 3;
    char *hs_type[] = {
        "headset_mic_1wire",
        "headset_mic_midtier",
        "headset_mic_oneseg",
    };
    hi->aid &= 0x7f;
    HS_LOG("[1wire]AID = 0x%x", hi->aid);
    if (hi->aid > type_num || hi->aid < 1) {
        *string = "1wire_unknown";
        return 14;
    } else {
        *string = hs_type[hi->aid - 1];
        HS_LOG("Report %s type, size %d", *string, sizeof(hs_type[hi->aid -1]));
        return sizeof(hs_type[hi->aid -1]);
    }
}
Example #20
0
/*One-wire button event handler*/
int button_1wire_work_func()
{
	int cnt = 0;
	char a_buf[20];
	int count = 0;
	int r,bflag;
	int key = 99;

	while(1){
		bflag=0;
		r=readFile(fp,a_buf,10);

		if(r>0){
			HS_LOG("Read %d bytes, count:%d, %s",r,count,a_buf);
			for(cnt = 0; cnt < r; cnt++){
				HS_LOG("0x%x \n", (int) a_buf[cnt]);
				if ((int)a_buf[cnt]==123){
					key = 3;
					bflag=1;
				}
				if ((int)a_buf[cnt]==125){
					key = 1;
					bflag=1;
				}
				if ((int)a_buf[cnt]==126){
					key = 2;
					bflag=1;
				}
				if ((int)a_buf[cnt]==127){
					key = 0;
					bflag=1;
			}
		}
		}
		count++;

		if(bflag == 1 || count == CHECK_COUNT)
			break;

		msleep(1);
	}
	return key;
}
static int hs_pmic_remote_threshold(uint32_t adc)
{
	int i = 0;
	int ret = 0;
	uint32_t status;
	struct hs_pmic_rpc_request req;
	struct hs_pmic_rpc_reply rep;

	HS_DBG_LOG();

	if (!(pmic_info->pdata.driver_flag & DRIVER_HS_PMIC_DYNAMIC_THRESHOLD))
		return 0;

	req.hs_controller = cpu_to_be32(pmic_info->pdata.hs_controller);
	req.hs_switch = cpu_to_be32(pmic_info->pdata.hs_switch);
	req.current_uA = cpu_to_be32(HS_PMIC_HTC_CURRENT_THRESHOLD);

	for (i = 0; i < ARRAY_SIZE(current_threshold_lut); i++) {
		if (adc >= current_threshold_lut[i].adc_min &&
		    adc <= current_threshold_lut[i].adc_max)
			req.current_uA = cpu_to_be32(current_threshold_lut[i].
						     current_uA);
	}

	ret = msm_rpc_call_reply(endpoint_current,
				 HS_PMIC_RPC_CLIENT_PROC_THRESHOLD,
				 &req, sizeof(req), &rep, sizeof(rep),
				 HS_RPC_TIMEOUT);

	if (ret < 0) {
		HS_LOG("Failed to send remote threshold RPC");
		return 0;
	} else {
		status = be32_to_cpu(rep.status);
		if (status != HS_PMIC_RPC_ERR_SUCCESS) {
			HS_LOG("Failed to set remote threshold");
			return 0;
		}
	}

	return 1;
}
Example #22
0
int hs_notify_key_event(int key_code)
{
	struct button_work *work;

	HS_DBG();

	if (hi->hs_35mm_type == HEADSET_INDICATOR) {
		HS_LOG("Not support remote control");
		return 1;
	}

	if (hi->hs_35mm_type == HEADSET_UNKNOWN_MIC ||
	    hi->hs_35mm_type == HEADSET_NO_MIC ||
	    hi->h2w_35mm_type == HEADSET_NO_MIC)
		update_mic_status(HS_DEF_MIC_DETECT_COUNT);
	else if (hi->hs_35mm_type == HEADSET_UNSTABLE)
		update_mic_status(0);
	else if (!hs_hpin_stable()) {
		HS_LOG("IGNORE key %d (Unstable HPIN)", key_code);
		return 1;
	} else if (hi->hs_35mm_type == HEADSET_UNPLUG && hi->is_ext_insert == 1) {
		HS_LOG("MIC status is changed from float, re-polling to decide accessory type");
		update_mic_status(HS_DEF_MIC_DETECT_COUNT);
		return 1;
	} else if (hi->hs_35mm_type == HEADSET_UNPLUG && hi->is_ext_insert == 1) {
		HS_LOG("MIC status is changed from float, re-polling to decide accessory type");
		update_mic_status(HS_DEF_MIC_DETECT_COUNT);
		return 1;
	} else {
		work = kzalloc(sizeof(struct button_work), GFP_KERNEL);
		if (!work) {
			HS_ERR("Failed to allocate button memory");
			return 1;
		}
		work->key_code = key_code;
		INIT_DELAYED_WORK(&work->key_work, button_35mm_work_func);
		queue_delayed_work(button_wq, &work->key_work,
				   HS_JIFFIES_BUTTON);
	}

	return 1;
}
static void enable_metrico_headset(int enable)
{
	HS_DBG();

	if (enable && !hi->metrico_status) {
#if 0
		enable_mos_test(1);
#endif
		hi->metrico_status = 1;
		HS_LOG("Enable metrico headset");
	}

	if (!enable && hi->metrico_status) {
#if 0
		enable_mos_test(0);
#endif
		hi->metrico_status = 0;
		HS_LOG("Disable metrico headset");
	}
}
void headset_button_event(int is_press, int type)
{
	HS_DBG();

	if (hi->hs_35mm_type == HEADSET_UNPLUG &&
	    hi->h2w_35mm_type == HEADSET_UNPLUG) {
		HS_LOG("IGNORE key %d (HEADSET_UNPLUG)", type);
		return;
	}

	if (!hs_hpin_stable()) {
		HS_LOG("IGNORE key %d (Unstable HPIN)", type);
		return;
	}

	if (!is_press)
		button_released(type);
	else if (!atomic_read(&hi->btn_state))
		button_pressed(type);
}
static void button_35mm_work_func(struct work_struct *work)
{
    int key;
    struct button_work *works;

    wake_lock_timeout(&hi->hs_wake_lock, HS_WAKE_LOCK_TIMEOUT);

    HS_DBG();

    works = container_of(work, struct button_work, key_work.work);
    hi->key_level_flag = works->key_code;

    if (hi->key_level_flag) {
        switch (hi->key_level_flag) {
        case 1:
            HS_LOG("3.5mm RC: Play Pressed");
            key = HS_MGR_KEYCODE_MEDIA;
            break;
        case 2:
            HS_LOG("3.5mm RC: BACKWARD Pressed");
            key = HS_MGR_KEYCODE_BACKWARD;
            break;
        case 3:
            HS_LOG("3.5mm RC: FORWARD Pressed");
            key = HS_MGR_KEYCODE_FORWARD;
            break;
        default:
            HS_LOG("3.5mm RC: WRONG Button Pressed");
            kfree(works);
            return;
        }
        headset_button_event(1, key);
    } else { /* key release */
        if (atomic_read(&hi->btn_state))
            headset_button_event(0, atomic_read(&hi->btn_state));
        else
            HS_LOG("3.5mm RC: WRONG Button Release");
    }

    kfree(works);
}
static void update_mic_status(int count)
{
	HS_DBG();

	if (hi->is_ext_insert) {
		HS_LOG("Start MIC status polling (%d)", count);
		cancel_delayed_work_sync(&mic_detect_work);
		hi->mic_detect_counter = count;
		queue_delayed_work(detect_wq, &mic_detect_work,
				   HS_JIFFIES_MIC_DETECT);
	}
}
static int hs_pmic_remote_adc(int *adc)
{
	int ret = 0;
	struct rpc_request_hdr req;
	struct hs_rpc_client_rep_adc rep;

	HS_DBG_LOG();

	ret = msm_rpc_call_reply(endpoint_adc, HS_RPC_CLIENT_PROC_ADC,
				 &req, sizeof(req), &rep, sizeof(rep),
				 HS_RPC_TIMEOUT);
	if (ret < 0) {
		HS_LOG("Failed to read remote ADC");
		return 0;
	}

	*adc = (int) be32_to_cpu(rep.adc);
	HS_LOG("Remote ADC %d (0x%X)", *adc, *adc);

	return 1;
}
int closeFile(struct file *fp)
{
    mm_segment_t old_fs;
    old_fs = get_fs();
    set_fs(KERNEL_DS);
    HS_LOG("Close: fp count = %d", --fp_count);
    filp_close(fp,NULL);
    set_fs(old_fs);
    mutex_unlock(&hi->mutex_lock);
    wake_unlock(&onewire_open_wake_lock);
    return 0;
}
/*One-wire button event handler*/
int button_1wire_work_func()
{
	int cnt = 0;
	char a_buf[20];
	int count = 0;
	int r,bflag;

	while(1){
		bflag=0;
		r=readFile(fp,a_buf,10);

		if(r>0){
			HS_LOG("Read %d bytes, count:%d, %s",r,count,a_buf);
			for(cnt = 0; cnt < r; cnt++){
				HS_LOG("0x%x \n", (int) a_buf[cnt]);
				if ((int)a_buf[cnt]==49){
					hi->key_level_flag = 3;
					bflag=1;
				}
				if ((int)a_buf[cnt]==50){
					hi->key_level_flag = 1;
					bflag=1;
				}
				if ((int)a_buf[cnt]==51){
					hi->key_level_flag = 2;
					bflag=1;
				}
				if ((int)a_buf[cnt]==52)
					bflag=1;
			}
		}
		count++;

		if(bflag == 1 || count == CHECK_COUNT)
			break;

		msleep(1);
	}
	return 1;
}
static void cancel_button_work_func(struct work_struct *work)
{
	int counter = 10, ret = 0;
	HS_DBG();

	ret = cancel_delayed_work(&button_gpio_work);

	if (ret)
            HS_LOG("cancel_delayed_work &button_gpio_work ok");

	while(counter--)
	{
		if(queue_delayed_work(button_wq, &button_gpio_work, unstable_jiffies))
		{
		    HS_LOG("queue_delayed_work &button_gpio_work ok");
		    break;
		}
		msleep(2);
	}

	queue_delayed_work(button_wq, &hs_key_irq_enable, irq_delay);
}