static irqreturn_t button_irq_handler(int irq, void *dev_id) { struct hsd_info *hi = (struct hsd_info *) dev_id; int value; wake_lock_timeout(&ear_hook_wake_lock, 2 * HZ); HSD_DBG("button_irq_handler"); // low:pressed, high:released if( gpio_cansleep(hi->gpio_swd) ) value = gpio_get_value_cansleep(hi->gpio_swd); else value = gpio_get_value(hi->gpio_swd); HSD_DBG("======= hi->gpio_swd : %d =======", value); if (value) queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); else queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_pressed), hi->latency_for_key ); return IRQ_HANDLED; }
static void serial_omap_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_omap_port *up = to_uart_omap_port(port); unsigned char mcr = 0; dev_dbg(up->port.dev, "serial_omap_set_mctrl+%d\n", up->port.line); if (mctrl & TIOCM_RTS) mcr |= UART_MCR_RTS; if (mctrl & TIOCM_DTR) mcr |= UART_MCR_DTR; if (mctrl & TIOCM_OUT1) mcr |= UART_MCR_OUT1; if (mctrl & TIOCM_OUT2) mcr |= UART_MCR_OUT2; if (mctrl & TIOCM_LOOP) mcr |= UART_MCR_LOOP; pm_runtime_get_sync(up->dev); up->mcr = serial_in(up, UART_MCR); up->mcr |= mcr; serial_out(up, UART_MCR, up->mcr); pm_runtime_mark_last_busy(up->dev); pm_runtime_put_autosuspend(up->dev); if (gpio_is_valid(up->DTR_gpio) && !!(mctrl & TIOCM_DTR) != up->DTR_active) { up->DTR_active = !up->DTR_active; if (gpio_cansleep(up->DTR_gpio)) schedule_work(&up->qos_work); else gpio_set_value(up->DTR_gpio, up->DTR_active != up->DTR_inverted); } }
static int gpio_keys_getval(int gpio) { int ret; if (gpio_cansleep(gpio)) ret = gpio_get_value_cansleep(gpio); else ret = gpio_get_value(gpio); return ret; }
static int gpio_keys_request_irq(int gpio, irq_handler_t isr, unsigned long flags, const char *name, void *data) { int ret; if (gpio_cansleep(gpio)) ret = request_threaded_irq(gpio_to_irq(gpio), NULL, isr, flags | IRQF_ONESHOT, name, data); else ret = request_irq(gpio_to_irq(gpio), isr, flags, name, data); return ret; }
bool is_4pole_earjack (void) { bool retVal; int err; if (gpio_cansleep(REMOTEKEY_DET)){ err=gpio_get_value_cansleep(REMOTEKEY_DET); dbg("gpio_get_value_cansleep(REMOTEKEY_DET) start\n"); }else{ err=gpio_get_value(REMOTEKEY_DET); dbg("gpio_get_value(REMOTEKEY_DET) start\n"); } retVal = (err>0) ? 1:0; return retVal; }
static void remove_headset(struct hsd_info *hi) { int has_mic = switch_get_state(&hi->sdev); HSD_DBG("remove_headset"); atomic_set(&hi->is_3_pole_or_not, HEADSET_POLE_INIT); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, HEADSET_NO_DEVICE); mutex_unlock(&hi->mutex_lock); if (atomic_read(&hi->irq_key_enabled)) { unsigned long irq_flags; local_irq_save(irq_flags); disable_irq(hi->irq_key); local_irq_restore(irq_flags); atomic_set(&hi->irq_key_enabled, FALSE); } if( atomic_read(&hi->btn_state) == HEADSET_BTN_PRESSED ) #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE queue_delayed_work(local_max1462x_workqueue, &(hi->work_for_key_released), hi->latency_for_key ); #else schedule_delayed_work(&(hi->work_for_key_released), hi->latency_for_key ); #endif input_report_switch(hi->input, SW_HEADPHONE_INSERT, 0); if (has_mic == HEADSET_WITH_MIC) { irq_set_irq_wake(hi->irq_key, 0); input_report_switch(hi->input, SW_MICROPHONE_INSERT, 0); //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) // set low to an external LDO for mic bias if (hi->set_headset_mic_bias) { hi->set_headset_mic_bias(FALSE); } else if( hi->external_ldo_mic_bias > 0 ) { gpio_cansleep(hi->external_ldo_mic_bias) ? gpio_set_value_cansleep(hi->external_ldo_mic_bias, 0) : gpio_set_value(hi->external_ldo_mic_bias, 0); } #endif //LGE_CHANGE_E 20130710 ilda.jung[Audio] Disable not using GPIO } input_sync(hi->input); }
static void button_released(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_key_released); struct ear_3button_info_table *table; int table_size = ARRAY_SIZE(max1462x_ear_3button_type_data); int i; if( gpio_cansleep(hi->gpio_det) ) { if( gpio_get_value_cansleep(hi->gpio_det) ) { //if( gpio_get_value_cansleep(hi->gpio_det) && !(atomic_read(&hi->btn_state) == HEADSET_BTN_PRESSED) ) { HSD_ERR("button_released but ear jack is plugged out already! just ignore the event.\n"); return; } } else { if( gpio_get_value(hi->gpio_det) ) { //if( gpio_get_value(hi->gpio_det) && !(atomic_read(&hi->btn_state) == HEADSET_BTN_PRESSED) ) { HSD_ERR("button_released but ear jack is plugged out already! just ignore the event.\n"); return; } } HSD_DBG("======= button_released ======="); for (i = 0; i < table_size; i++) { table = &max1462x_ear_3button_type_data[i]; if (table->PRESS_OR_NOT) { atomic_set(&hi->btn_state, HEADSET_BTN_RELEASED); switch(table->ADC_HEADSET_BUTTON) { case KEY_MEDIA : input_report_key(hi->input, KEY_MEDIA, 0); break; case KEY_VOLUMEUP : input_report_key(hi->input, KEY_VOLUMEUP, 0); break; case KEY_VOLUMEDOWN : input_report_key(hi->input, KEY_VOLUMEDOWN, 0); break; } table->PRESS_OR_NOT = 0; input_sync(hi->input); break; } } }
static int dht22_probe(struct platform_device *pdev) { struct device* dev; struct dht22_platform_data* pdata; struct dht22_priv* priv; dev = &pdev->dev; priv = devm_kzalloc(dev,sizeof(struct dht22_priv),GFP_KERNEL); if (!priv) return -ENOMEM; pdata = dev->platform_data; if (pdata) priv->gpio = pdata->gpio; else priv->gpio = of_get_gpio(dev->of_node, 0); dev_info(dev, "Creating dht22 for gpio %d\n", priv->gpio); if(!gpio_is_valid(priv->gpio)) { dev_err(dev, "Invalid GPIO number : %u",priv->gpio); return -EINVAL; } if(gpio_cansleep(priv->gpio)) { dev_err(dev, "Calls for GPIO number %u can sleep, driver can't use it",priv->gpio); return -EFAULT; } if (gpio_request_one(priv->gpio, GPIOF_IN, dev_name(dev))) { dev_err(dev, "Can't request GPIO number %u",priv->gpio); return -EFAULT; } request_irq(gpio_to_irq(priv->gpio), dht22_handler, IRQF_TRIGGER_FALLING | IRQF_NO_THREAD, dev_name(dev), dev); sysfs_create_group(&dev->kobj, &dht22_attr_group); platform_set_drvdata(pdev,priv); return 0; }
static void detect_work(struct work_struct *work) { int state = 0; struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct hsd_info *hi = container_of(dwork, struct hsd_info, work); HSD_DBG("detect_work"); if( gpio_cansleep(hi->gpio_det) ) state = gpio_get_value_cansleep(hi->gpio_det); else state = gpio_get_value(hi->gpio_det); if( state == 1 ) { // gpio_det high - jack out if( switch_get_state(&hi->sdev) != HEADSET_NO_DEVICE ) { HSD_DBG("======= LGE headset removing ======="); remove_headset(hi); #ifdef CONFIG_LGE_BROADCAST_ONESEG isdbt_hw_antenna_switch(0); ear_state = 0; #endif } else { HSD_DBG("err_invalid_state state = %d\n", state); } } else { // gpio_det low - jack in if( switch_get_state(&hi->sdev) == HEADSET_NO_DEVICE ) { HSD_DBG("********** LGE headset inserting **********"); insert_headset(hi); #ifdef CONFIG_LGE_BROADCAST_ONESEG isdbt_hw_antenna_switch(1); ear_state = 1; #endif } else { HSD_DBG("err_invalid_state state = %d\n", state); } } }
static enum hrtimer_restart gpio_pwm_timeout(struct hrtimer *t) { struct gpio_pwm *gp = container_of(t, struct gpio_pwm, timer); ktime_t tnew; if (unlikely(gp->pwm.channels[0].duty_ticks == 0)) gp->active = 0; else if (unlikely(gp->pwm.channels[0].duty_ticks == gp->pwm.channels[0].period_ticks)) gp->active = 1; else gp->active ^= 1; if (gpio_cansleep(gp->gpio)) schedule_work(&gp->work); else gpio_pwm_work(&gp->work); if (!gp->active && gp->pwm.channels[0].callback) gp->pwm.channels[0].callback(&gp->pwm.channels[0]); if (unlikely(!gp->active && (gp->pwm.channels[0].flags & BIT(FLAG_STOP)))) { clear_bit(FLAG_STOP, &gp->pwm.channels[0].flags); complete_all(&gp->pwm.channels[0].complete); return HRTIMER_NORESTART; } if (gp->active) tnew = ktime_set(0, gp->pwm.channels[0].duty_ticks); else tnew = ktime_set(0, gp->pwm.channels[0].period_ticks - gp->pwm.channels[0].duty_ticks); hrtimer_start(&gp->timer, tnew, HRTIMER_MODE_REL); return HRTIMER_NORESTART; }
static void insert_headset(struct hsd_info *hi) { int earjack_type; HSD_DBG("insert_headset"); // set irq to wake up in sleep mode irq_set_irq_wake(hi->irq_key, 1); //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) // set high to an external LDO for mic bias if (hi->set_headset_mic_bias) { hi->set_headset_mic_bias(TRUE); } else if( hi->external_ldo_mic_bias > 0 ) { gpio_cansleep(hi->external_ldo_mic_bias) ? gpio_set_value_cansleep(hi->external_ldo_mic_bias, 1) : gpio_set_value(hi->external_ldo_mic_bias, 1); } #endif //LGE_CHANGE_E20130710 ilda.jung[Audio] Disable not using GPIO // set mode pin high gpio_direction_output(hi->gpio_mode, 1); msleep(25); /* check if 3-pole or 4-pole * 1. read gpio_swd * 2. check if 3-pole or 4-pole * 3-1. NOT regiter irq with gpio_swd if 3-pole. complete. * 3-2. regiter irq with gpio_swd if 4-pole * 4. read MPP1 and decide a pressed key when interrupt occurs */ /* 1. read gpio_swd */ if( gpio_cansleep(hi->gpio_swd) ) earjack_type = gpio_get_value_cansleep(hi->gpio_swd); else earjack_type = gpio_get_value(hi->gpio_swd); /* 2. check if 3-pole or 4-pole */ if ( earjack_type == HEADSET_POLE_4 ) {// high HSD_DBG("======= 4 polarity earjack ======="); atomic_set(&hi->is_3_pole_or_not, HEADSET_POLE_4); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, HEADSET_WITH_MIC); mutex_unlock(&hi->mutex_lock); if (!atomic_read(&hi->irq_key_enabled)) { unsigned long irq_flags; HSD_DBG("irq_key_enabled = enable"); local_irq_save(irq_flags); enable_irq(hi->irq_key); local_irq_restore(irq_flags); atomic_set(&hi->irq_key_enabled, TRUE); } // set mode pin high #if 1 //gpio_direction_output(hi->gpio_mode, 1); #else gpio_tlmm_config( // GPIOMUX_FUNC_GPIO GPIO_CFG(hi->gpio_mode, 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP, 0xf), GPIO_CFG_ENABLE); #endif input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1); input_report_switch(hi->input, SW_MICROPHONE_INSERT, 1); input_sync(hi->input); } else {// low HSD_DBG("********** 3 polarity earjack **********"); atomic_set(&hi->is_3_pole_or_not, HEADSET_POLE_3); mutex_lock(&hi->mutex_lock); switch_set_state(&hi->sdev, HEADSET_NO_MIC); mutex_unlock(&hi->mutex_lock); irq_set_irq_wake(hi->irq_key, 0); //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) // set low to an external LDO for mic bias if (hi->set_headset_mic_bias) { hi->set_headset_mic_bias(FALSE); } else if( hi->external_ldo_mic_bias > 0 ) { gpio_cansleep(hi->external_ldo_mic_bias) ? gpio_set_value_cansleep(hi->external_ldo_mic_bias, 0) : gpio_set_value(hi->external_ldo_mic_bias, 0); } #endif //LGE_CHANGE_E 20130710 ilda.jung[Audio] Disable not using GPIO // set mode pin high-z #if 1 gpio_direction_input(hi->gpio_mode); #else gpio_tlmm_config( // GPIOMUX_FUNC_GPIO GPIO_CFG(hi->gpio_mode, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); #endif input_report_switch(hi->input, SW_HEADPHONE_INSERT, 1); input_sync(hi->input); } }
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; struct gpio_kp *kp; struct gpio_event_matrix_info *mi; mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { /* TODO: disable scanning */ return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; pr_err("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } key_count = mi->ninputs * mi->noutputs; *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_devs = input_devs; kp->keypad_info = mi; for (i = 0; i < key_count; i++) { unsigned short keyentry = mi->keymap[i]; unsigned short keycode = keyentry & MATRIX_KEY_MASK; unsigned short dev = keyentry >> MATRIX_CODE_BITS; if (dev >= input_devs->count) { pr_err("gpiomatrix: bad device index %d >= " "%d for key code %d\n", dev, input_devs->count, keycode); err = -EINVAL; goto err_bad_keymap; } if (keycode && keycode <= KEY_MAX) input_set_capability(input_devs->dev[dev], EV_KEY, keycode); } set_bit(KEY_BACK & KEY_MAX, input_devs->dev[0]->keybit); set_bit(KEY_HOME & KEY_MAX, input_devs->dev[0]->keybit); for (i = 0; i < mi->noutputs; i++) { if (gpio_cansleep(mi->output_gpios[i])) { pr_err("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_request_output_gpio_failed; } err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE) err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); else { unsigned gpio_config = GPIO_CFG(mi->output_gpios[i], 0, GPIO_INPUT, GPIO_PULL_UP, GPIO_2MA); gpio_tlmm_config(gpio_config, GPIO_ENABLE); err = gpio_direction_input(mi->output_gpios[i]); } if (err) { pr_err("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } err = gpio_direction_input(mi->input_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } kp->current_output = mi->noutputs; kp->key_state_changed = 1; hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); #ifdef CONFIG_HUAWEI_BACK_KEY_MULTI kp->back_pressed = FALSE; #endif kp->timer.function = gpio_keypad_timer_func; hrtimer_init(&kp->back_key_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->back_key_timer.function = back_key_timer_func; wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " "%s%s in %s mode\n", input_devs->dev[0]->name, (input_devs->count > 1) ? "..." : "", kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); hrtimer_cancel(&kp->timer); wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } err_bad_keymap: kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; struct gpio_kp *kp; struct gpio_event_matrix_info *mi; #if defined(CONFIG_MACH_RANT3) || defined(CONFIG_MACH_REALITY2) || defined(CONFIG_MACH_VINO) || defined(CONFIG_MACH_ROOKIE) || defined(CONFIG_MACH_ESCAPE) || defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_GIOS) /* Implementation for sysfs entries , creating Keypad-backlight class */ bl_class = class_create(THIS_MODULE, "keypad-backlight"); if ( bl_class) { printk(KERN_WARNING "Unable to create Keypad Backlight class \n"); } /* Creating the device backlight under keypad-backlight class */ kpd_dev = device_create( bl_class, NULL, 0, NULL, "backlight"); if (!kpd_dev){ class_destroy(bl_class); printk("Failed to create device(keypad backlight) \n"); } if (device_create_file(kpd_dev, &dev_attr_key_pressed) < 0) printk("Failed to create device file(%s)!\n", dev_attr_key_pressed.attr.name); if (device_create_file(kpd_dev, &dev_attr_backlight_ctrl) < 0) printk("Failed to create device file(%s)!\n", dev_attr_backlight_ctrl.attr.name); if (device_create_file(kpd_dev, &dev_attr_backlight_lpm_ctrl) < 0) printk("Failed to create device file(%s)!\n", dev_attr_backlight_lpm_ctrl.attr.name); #if defined(CONFIG_MACH_VINO) || defined(CONFIG_MACH_GIOS) if (device_create_file(kpd_dev, &dev_attr_volumnkey_ctrl) < 0) printk("Failed to create device file(%s)!\n", dev_attr_volumnkey_ctrl.attr.name); #endif /* Creating device attributes for setting keypad backlight time */ if (device_create_file(kpd_dev, &bl_keypad_attributes[0]) < 0){ printk("Failed to create device attributes for Keypad Backlight \n"); device_destroy(bl_class,0); class_destroy(bl_class); } /* Initializing delayed work for Back light off */ INIT_DELAYED_WORK(&backlightoff, keypad_backlightoff_work); #endif mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { #if defined(CONFIG_MACH_RANT3) || defined(CONFIG_MACH_REALITY2) || defined(CONFIG_MACH_VINO) || defined(CONFIG_MACH_ROOKIE) || defined(CONFIG_MACH_ESCAPE) || defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_GIOS) if(func == GPIO_EVENT_FUNC_SUSPEND) keypad_backlight_power(OFF); else keypad_backlight_power(ON); #endif /* TODO: disable scanning */ return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; pr_err("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } key_count = mi->ninputs * mi->noutputs; pgpio_key=*data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_devs = input_devs; kp->keypad_info = mi; for (i = 0; i < key_count; i++) { unsigned short keyentry = mi->keymap[i]; unsigned short keycode = keyentry & MATRIX_KEY_MASK; unsigned short dev = keyentry >> MATRIX_CODE_BITS; if (dev >= input_devs->count) { pr_err("gpiomatrix: bad device index %d >= " "%d for key code %d\n", dev, input_devs->count, keycode); err = -EINVAL; goto err_bad_keymap; } if (keycode && keycode <= KEY_MAX) input_set_capability(input_devs->dev[dev], EV_KEY, keycode); } #if defined(CONFIG_MACH_ESCAPE) input_set_capability(kp->input_devs->dev[0], EV_SW, SW_LID); if(gpio_get_value(HALL_GPIO)) kp->input_devs->dev[0]->sw[SW_LID] = 0; else kp->input_devs->dev[0]->sw[SW_LID] = 1; #endif for (i = 0; i < mi->noutputs; i++) { err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (gpio_cansleep(mi->output_gpios[i])) { pr_err("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_output_gpio_configure_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE){ #if defined(CONFIG_MACH_RANT3) || defined(CONFIG_MACH_ESCAPE) #if defined(CONFIG_MACH_RANT3) if(hw_version < 6) #endif { err = gpio_tlmm_config(GPIO_CFG(mi->output_gpios[i] , 0, GPIO_CFG_OUTPUT, GPIO_CFG_PULL_UP,GPIO_CFG_2MA), GPIO_CFG_ENABLE); printk("Gpio config %d return %d \r\n",mi->output_gpios[i] ,err); if (err) { pr_err("gpiomatrix: gpio_tlmm_config failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } } #endif err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); } else err = gpio_direction_input(mi->output_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } #if defined (CONFIG_MACH_ROOKIE) || defined(CONFIG_MACH_ESCAPE)// || defined(CONFIG_MACH_GIO) if ( i >= mi->ninputs-2) // ( (i == 2) || (i == 3)) err = gpio_tlmm_config(GPIO_CFG(mi->input_gpios[i] , 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL,GPIO_CFG_2MA), GPIO_CFG_ENABLE); else #endif #if defined(CONFIG_MACH_RANT3) if(hw_version < 6) { err = gpio_tlmm_config(GPIO_CFG(mi->input_gpios[i] , 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN,GPIO_CFG_2MA), GPIO_CFG_ENABLE); pr_err("Gpio config %d return %d\r\n",mi->input_gpios[i] ,err); if (err) { printk("gpiomatrix: gpio_tlmm_config failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } } #elif defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_VINO) || defined(CONFIG_MACH_GIOS) #else err = gpio_tlmm_config(GPIO_CFG(mi->input_gpios[i] , 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_DOWN,GPIO_CFG_2MA), GPIO_CFG_ENABLE); pr_err("Gpio config %d return %d\r\n",mi->input_gpios[i] ,err); if (err) { printk("gpiomatrix: gpio_tlmm_config failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } #endif err = gpio_direction_input(mi->input_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } for (i = 0; i < mi->ninputs; i++) { printk("Reading Input GPIO %d at init is %d \r\n",mi->input_gpios[i],gpio_get_value(mi->input_gpios[i])); } kp->current_output = mi->noutputs; kp->key_state_changed = 1; hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->timer.function = gpio_keypad_timer_func; wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; pr_debug("GPIO Matrix Keypad Driver: Start keypad matrix for " "%s%s in %s mode\n", input_devs->dev[0]->name, (input_devs->count > 1) ? "..." : "", kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); hrtimer_start(&kp->timer, ktime_set(0, 10000), HRTIMER_MODE_REL); #if defined(CONFIG_MACH_RANT3) || defined(CONFIG_MACH_VINO) || defined(CONFIG_MACH_REALITY2) || defined(CONFIG_MACH_ROOKIE) || defined(CONFIG_MACH_ESCAPE) || defined(CONFIG_MACH_GIO) || defined(CONFIG_MACH_GIOS) early_suspend.suspend = keypad_early_suspend; early_suspend.resume = keypad_late_resume; register_early_suspend(&early_suspend); backlight_flag = 1; keypad_backlight_power(OFF); spin_lock_init(&keypad_led_lock); #endif return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); hrtimer_cancel(&kp->timer); wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } err_bad_keymap: kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; struct gpio_kp *kp; struct gpio_event_matrix_info *mi; mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { /* TODO: disable scanning */ return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; pr_err("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } printk("[%s:%d] hw rev = %d\n", __func__, __LINE__, board_hw_revision); #if defined(CONFIG_MACH_EUROPA) if(board_hw_revision >= 3) { mi->keymap[(0)*mi->ninputs + (1)] = KEY_RESERVED; mi->keymap[(3)*mi->ninputs + (1)] = KEY_VOLUMEDOWN; mi->keymap[(3)*mi->ninputs + (4)] = KEY_VOLUMEUP; if(board_hw_revision >= 4) { mi->input_gpios[4] = 76; } } #endif #if defined(CONFIG_MACH_CALLISTO) // hsil input_set_capability(input_devs->dev[0], EV_SW, SW_LID); #endif key_count = mi->ninputs * mi->noutputs; *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_devs = input_devs; kp->keypad_info = mi; for (i = 0; i < key_count; i++) { unsigned short keyentry = mi->keymap[i]; unsigned short keycode = keyentry & MATRIX_KEY_MASK; unsigned short dev = keyentry >> MATRIX_CODE_BITS; if (dev >= input_devs->count) { pr_err("gpiomatrix: bad device index %d >= " "%d for key code %d\n", dev, input_devs->count, keycode); err = -EINVAL; goto err_bad_keymap; } if (keycode && keycode <= KEY_MAX) input_set_capability(input_devs->dev[dev], EV_KEY, keycode); } input_set_capability(input_devs->dev[0],EV_KEY, KEY_END); // for COOPER #if defined(CONFIG_MACH_COOPER) || defined(CONFIG_MACH_BENI) || defined(CONFIG_MACH_TASS) || defined(CONFIG_MACH_LUCAS) #if defined(CONFIG_KERNEL_SEC_MMICHECK) for(i = 0 ; i < ARRAY_SIZE(mmi_keycode) ; i++) input_set_capability(input_devs->dev[0],EV_KEY, mmi_keycode[i]); // for COOPER #endif #endif for (i = 0; i < mi->noutputs; i++) { if (gpio_cansleep(mi->output_gpios[i])) { pr_err("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_request_output_gpio_failed; } err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE) err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); else err = gpio_direction_input(mi->output_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } err = gpio_direction_input(mi->input_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } // for COOPER err = gpio_request(GPIO_POWERKEY, "gpio_powerkey"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input GPIO_POWERKEY %d\n", GPIO_POWERKEY); goto err_request_input_gpio_failed; } err = gpio_direction_input(GPIO_POWERKEY); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input GPIO_POWERKEY %d\n", GPIO_POWERKEY); goto err_gpio_direction_input_failed; } kp->current_output = mi->noutputs; kp->key_state_changed = 1; hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->timer.function = gpio_keypad_timer_func; wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " "%s%s in %s mode\n", input_devs->dev[0]->name, (input_devs->count > 1) ? "..." : "", kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); hrtimer_cancel(&kp->timer); wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } err_bad_keymap: kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; #ifdef CONFIG_KEYBOARD_WAKEUP int wakeup_keys_status; int irq; static int irq_status = 1; #endif struct gpio_kp *kp; struct gpio_event_matrix_info *mi; // pr_info("[KEY TEST] %s, %d \n", __func__, __LINE__); mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { /* TODO: disable scanning */ #ifdef CONFIG_KEYBOARD_WAKEUP wakeup_keys_status = gpio_event_get_wakeup_keys_status() & 0x01; if (irq_status != wakeup_keys_status) irq_status = wakeup_keys_status; else return 0; for (i = 0; i < mi->ninputs; i++) { irq = gpio_to_irq(mi->input_gpios[i]); if (irq_status == 1) err = enable_irq_wake(irq); else err = disable_irq_wake(irq); } /* HOME Key is wakeup source */ for (i = 0; i < mi->nwakeups; i++) { irq = gpio_to_irq(mi->wakeup_gpios[i]); err = enable_irq_wake(irq); } #endif return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; pr_err("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } key_count = mi->ninputs * mi->noutputs; pgpio_key = *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_devs = input_devs; kp->keypad_info = mi; for (i = 0; i < key_count; i++) { unsigned short keyentry = mi->keymap[i]; unsigned short keycode = keyentry & MATRIX_KEY_MASK; unsigned short dev = keyentry >> MATRIX_CODE_BITS; if (dev >= input_devs->count) { pr_err("gpiomatrix: bad device index %d >= " "%d for key code %d\n", dev, input_devs->count, keycode); err = -EINVAL; goto err_bad_keymap; } if (keycode && keycode <= KEY_MAX) input_set_capability(input_devs->dev[dev], EV_KEY, keycode); } for (i = 0; i < mi->noutputs; i++) { err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (gpio_cansleep(mi->output_gpios[i])) { pr_err("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_output_gpio_configure_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE) err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); else err = gpio_direction_input(mi->output_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } err = gpio_direction_input(mi->input_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } kp->current_output = mi->noutputs; kp->key_state_changed = 1; hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->timer.function = gpio_keypad_timer_func; wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; #ifdef CONFIG_KEYBOARD_WAKEUP kpd_dev = device_create(sec_class, NULL, 0, NULL, "sec_key"); if (!kpd_dev) printk(KERN_WARNING "Failed to create device(sec_key)!\n"); if (device_create_file(kpd_dev, &dev_attr_sec_key_pressed) < 0) printk(KERN_WARNING "Failed to create file(%s)!\n" , dev_attr_sec_key_pressed.attr.name); #endif pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for " "%s%s in %s mode\n", input_devs->dev[0]->name, (input_devs->count > 1) ? "..." : "", kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); hrtimer_cancel(&kp->timer); wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } err_bad_keymap: kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }
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"); hi = kzalloc(sizeof(struct hsd_info), GFP_KERNEL); if (NULL == hi) { HSD_ERR("Failed to allloate headset per device info\n"); return -ENOMEM; } platform_set_drvdata(pdev, hi); // initialize internal variables atomic_set(&hi->btn_state, HEADSET_BTN_INIT); atomic_set(&hi->is_3_pole_or_not, HEADSET_POLE_INIT); // set key code hi->key_code = pdata->key_code; // KEY_RESERVED(0), KEY_MEDIA(226), KEY_VOLUMEUP(115) or KEY_VOLUMEDOWN(114) // set GPIO number for each pin hi->gpio_mode = pdata->gpio_mode; hi->gpio_det = pdata->gpio_det; hi->gpio_swd = pdata->gpio_swd; // set delayed time for latency hi->latency_for_detection = msecs_to_jiffies(pdata->latency_for_detection); HSD_DBG("jiffies of hi->latency_for_detection : %u \n", hi->latency_for_detection); hi->latency_for_key = msecs_to_jiffies(pdata->latency_for_key); HSD_DBG("jiffies of hi->latency_for_key : %u \n", hi->latency_for_key); hi->adc_mpp_num = pdata->adc_mpp_num; HSD_DBG("hi->adc_mpp_num : %u \n", hi->adc_mpp_num); hi->adc_channel = pdata->adc_channel; HSD_DBG("hi->adc_channel : %u \n", hi->adc_channel); //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) // set gpio for an external LDO control if( pdata->external_ldo_mic_bias > 0 ) { hi->external_ldo_mic_bias = pdata->external_ldo_mic_bias; HSD_DBG("control an external LDO(GPIO# %u) for MIC BIAS", hi->external_ldo_mic_bias); } else { hi->external_ldo_mic_bias = 0; HSD_DBG("don't control an external LDO for MIC"); } // set callback function for an external LDO control if( pdata->set_headset_mic_bias!= NULL ) { hi->set_headset_mic_bias = pdata->set_headset_mic_bias; HSD_DBG("set a func pointer of an external LDO for MIC"); } else { pdata->set_headset_mic_bias = NULL; HSD_DBG("don't set a func pointer of an external LDO for MIC"); } #endif //LGE_CHANGE_E 20130710 ilda.jung[Audio] Disable not using GPIO mutex_init(&hi->mutex_lock); INIT_DELAYED_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); // initialize gpio_mode // set gpio_mode high as a default, and set mode among high,low,high-Z after deciding 3 or 4 polarity ret = gpio_request(hi->gpio_mode, "gpio_mode"); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (gpio_mode) gpio_request\n", hi->gpio_mode); goto error_01; } ret = gpio_direction_output(hi->gpio_mode, 1); if (ret < 0) { HSD_ERR("Failed to configure gpio%d (gpio_mode) gpio_direction_input\n", hi->gpio_mode); goto error_01; } // initialize gpio_det ret = gpio_request(hi->gpio_det, "gpio_det"); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (gpio_det) gpio_request\n", hi->gpio_det); goto error_02; } ret = gpio_direction_input(hi->gpio_det); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (gpio_det) gpio_direction_input\n", hi->gpio_det); goto error_02; } // initialize gpio_swd ret = gpio_request(hi->gpio_swd, "gpio_swd"); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (gpio_swd) gpio_request\n", hi->gpio_swd); goto error_03; } ret = gpio_direction_input(hi->gpio_swd); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (gpio_swd) gpio_direction_input\n", hi->gpio_swd); goto error_03; } //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) // initialize external_ldo_mic_bias if( hi->external_ldo_mic_bias > 0 ) { ret = gpio_request(hi->external_ldo_mic_bias, "external_ldo_mic_bias"); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (external_ldo_mic_bias) gpio_request\n", hi->external_ldo_mic_bias); goto error_04; } ret = gpio_direction_output(hi->external_ldo_mic_bias, 0); if (ret < 0) { HSD_ERR("Failed to configure gpio%u (external_ldo_mic_bias) gpio_direction_input\n", hi->external_ldo_mic_bias); goto error_04; } HSD_DBG("hi->external_ldo_mic_bias value = %d \n", gpio_cansleep(hi->external_ldo_mic_bias) ? gpio_get_value_cansleep(hi->external_ldo_mic_bias) : gpio_get_value(hi->external_ldo_mic_bias)); } #endif //LGE_CHANGE_E 20130710 ilda.jung[Audio] Disable not using GPIO /* initialize irq of detection */ hi->irq_detect = gpio_to_irq(hi->gpio_det); 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; } 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"); 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_05; } /* initialize irq of gpio_key */ hi->irq_key = gpio_to_irq(hi->gpio_swd); 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"); goto error_06; } disable_irq(hi->irq_key); #if 0 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; } #endif /* 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_06; } /* initialize input device */ hi->input = input_allocate_device(); if (!hi->input) { HSD_ERR("Failed to allocate input device\n"); ret = -ENOMEM; goto error_07; } hi->input->name = pdata->keypad_name; hi->input->id.vendor = 0x0001; hi->input->id.product = 1; hi->input->id.version = 1; // [START] // headset tx noise { struct pm8xxx_adc_chan_result result; int acc_read_value = 0; int i, rc; int count = 3; for (i = 0; i < count; i++) { rc = pm8xxx_adc_mpp_config_read(hi->adc_mpp_num, hi->adc_channel, &result); if (rc < 0) { if (rc == -ETIMEDOUT) { HSD_ERR("[DEBUG]adc read timeout \n"); } else { HSD_ERR("[DEBUG]adc read error - %d\n", rc); } } else { acc_read_value = (int)result.physical; HSD_DBG("%s: acc_read_value - %d\n", __func__, (int)result.physical); break; } } } // [END] /*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); 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_08; } // to detect in initialization with eacjack insertion if( gpio_cansleep(hi->gpio_det) ) { if( !gpio_get_value_cansleep(hi->gpio_det) ) { #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE queue_delayed_work(local_max1462x_workqueue, &(hi->work), 0); #else schedule_delayed_work(&(hi->work), 0); #endif } } else { if( !gpio_get_value_cansleep(hi->gpio_det) ) { #ifdef CONFIG_MAX1462X_USE_LOCAL_WORK_QUEUE queue_delayed_work(local_max1462x_workqueue, &(hi->work), 0); #else schedule_delayed_work(&(hi->work), 0); #endif } } return ret; error_08: input_free_device(hi->input); error_07: switch_dev_unregister(&hi->sdev); error_06: free_irq(hi->irq_key, 0); error_05: free_irq(hi->irq_detect, 0); //LGE_CHANGE_S 20130710 ilda.jung[Audio] Disable not using GPIO #if !defined(CONFIG_MACH_APQ8064_AWIFI) error_04: if( hi->external_ldo_mic_bias > 0 ) gpio_free(hi->external_ldo_mic_bias); #endif //LGE_CHANGE_E 20130710 ilda.jung[Audio] Disable not using GPIO error_03: gpio_free(hi->gpio_swd); error_02: gpio_free(hi->gpio_det); error_01: mutex_destroy(&hi->mutex_lock); kfree(hi); return ret; }
static int __devinit gpio_ir_recv_probe(struct platform_device *pdev) { struct gpio_rc_dev *gpio_dev; struct rc_dev *rcdev; const struct gpio_ir_recv_platform_data *pdata = pdev->dev.platform_data; int rc; if (!pdata) return -EINVAL; if (pdata->gpio_nr < 0) return -EINVAL; gpio_dev = kzalloc(sizeof(struct gpio_rc_dev), GFP_KERNEL); if (!gpio_dev) return -ENOMEM; rcdev = rc_allocate_device(); if (!rcdev) { rc = -ENOMEM; goto err_allocate_device; } rcdev->driver_type = RC_DRIVER_IR_RAW; rcdev->allowed_protos = RC_TYPE_ALL; rcdev->input_name = GPIO_IR_DEVICE_NAME; rcdev->input_id.bustype = BUS_HOST; rcdev->driver_name = GPIO_IR_DRIVER_NAME; rcdev->map_name = RC_MAP_SAMSUNG_NECX; gpio_dev->rcdev = rcdev; gpio_dev->gpio_nr = pdata->gpio_nr; gpio_dev->active_low = pdata->active_low; gpio_dev->can_wakeup = pdata->can_wakeup; gpio_dev->gpio_irq_latency = pdata->swfi_latency + 1; gpio_dev->pm_qos_vote = 0; rc = gpio_request(pdata->gpio_nr, "gpio-ir-recv"); if (rc < 0) goto err_gpio_request; gpio_dev->can_sleep = gpio_cansleep(pdata->gpio_nr); rc = gpio_direction_input(pdata->gpio_nr); if (rc < 0) goto err_gpio_direction_input; rc = rc_register_device(rcdev); if (rc < 0) { dev_err(&pdev->dev, "failed to register rc device\n"); goto err_register_rc_device; } platform_set_drvdata(pdev, gpio_dev); rc = request_any_context_irq(gpio_to_irq(pdata->gpio_nr), gpio_ir_recv_irq, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "gpio-ir-recv-irq", gpio_dev); if (rc < 0) goto err_request_irq; if (gpio_dev->can_wakeup) { pm_qos_add_request(&gpio_dev->pm_qos_req, PM_QOS_CPU_DMA_LATENCY, PM_QOS_DEFAULT_VALUE); device_init_wakeup(&pdev->dev, pdata->can_wakeup); setup_timer(&gpio_dev->gpio_ir_timer, gpio_ir_timer, (unsigned long)gpio_dev); } return 0; err_request_irq: platform_set_drvdata(pdev, NULL); rc_unregister_device(rcdev); err_register_rc_device: err_gpio_direction_input: gpio_free(pdata->gpio_nr); err_gpio_request: rc_free_device(rcdev); rcdev = NULL; err_allocate_device: kfree(gpio_dev); return rc; }
int gpio_event_matrix_func(struct input_dev *input_dev, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; struct gpio_kp *kp; struct gpio_event_matrix_info *mi; mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { /* TODO: disable scanning */ return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; pr_err("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } key_count = mi->ninputs * mi->noutputs; *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; pr_err("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_dev = input_dev; kp->keypad_info = mi; set_bit(EV_KEY, input_dev->evbit); for (i = 0; i < key_count; i++) { if (mi->keymap[i]) set_bit(mi->keymap[i] & KEY_MAX, input_dev->keybit); } for (i = 0; i < mi->noutputs; i++) { if (gpio_cansleep(mi->output_gpios[i])) { pr_err("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_request_output_gpio_failed; } err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE) err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); else err = gpio_direction_input(mi->output_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { pr_err("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } err = gpio_direction_input(mi->input_gpios[i]); if (err) { pr_err("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } kp->current_output = mi->noutputs; kp->key_state_changed = 1; hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->timer.function = gpio_keypad_timer_func; wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for %s " "in %s mode\n", input_dev->name, kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); hrtimer_cancel(&kp->timer); wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }
static void button_pressed(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_key_pressed); struct pm8xxx_adc_chan_result result; struct ear_3button_info_table *table; int acc_read_value=0, i=0, rc=0, table_size=ARRAY_SIZE(max1462x_ear_3button_type_data); HSD_DBG("button_pressed begin \n"); if( gpio_cansleep(hi->gpio_det) ) { if( gpio_get_value_cansleep(hi->gpio_det) ) { HSD_ERR("button_pressed but ear jack is plugged out already! just ignore the event.\n"); return; } } else { if( gpio_get_value(hi->gpio_det) ) { HSD_ERR("button_pressed but ear jack is plugged out already! just ignore the event.\n"); return; } } for (i = 0; i < table_size; i++) { rc = pm8xxx_adc_mpp_config_read(hi->adc_mpp_num, hi->adc_channel, &result); if (rc < 0) { if (rc == -ETIMEDOUT) { HSD_ERR("button_pressed : adc read timeout[try count:%d]\n", i+1); } else { HSD_ERR("button_pressed : adc read error - rc:%d[try count:%d]\n", rc, i+1); } } else { acc_read_value = (int)result.physical; HSD_DBG("======= acc_read_value - %d [try count:%d] =======\n", (int)result.physical, i+1); if( acc_read_value > VDOWN_MAX ) { HSD_DBG("********** read again acc_read_value [try count:%d] **********\n", i+1); continue; } // if success, exit from loop break; } } for (i = 0; i < table_size; i++) { table = &max1462x_ear_3button_type_data[i]; // [AUDIO_BSP] 20130110, junday.lee, include min value '=' for 1 button earjack (ADC value= 0) if ((acc_read_value <= table->PERMISS_REANGE_MAX)&&(acc_read_value >= table->PERMISS_REANGE_MIN)) { atomic_set(&hi->btn_state, HEADSET_BTN_PRESSED); switch(table->ADC_HEADSET_BUTTON) { case KEY_MEDIA: input_report_key(hi->input, KEY_MEDIA, 1); HSD_DBG("********** KEY_MEDIA **********\n"); break; case KEY_VOLUMEUP: input_report_key(hi->input, KEY_VOLUMEUP, 1); HSD_DBG("********** KEY_VOLUMEUP **********\n"); break; case KEY_VOLUMEDOWN: input_report_key(hi->input, KEY_VOLUMEDOWN, 1); HSD_DBG("********** KEY_VOLUMEDOWN **********\n"); break; } table->PRESS_OR_NOT = 1; input_sync(hi->input); break; } } HSD_DBG("button_pressed end \n"); }
static int archer_led_probe(struct platform_device *pdev) { struct led_platform_data *pdata = pdev->dev.platform_data; struct led_info *cur_led; struct archer_led_data *leds_data, *led_dat; int i, ret = 0; printk("[LED] %s +\n", __func__); if (!pdata) return -EBUSY; leds_data = kzalloc(sizeof(struct archer_led_data) * pdata->num_leds, GFP_KERNEL); if (!leds_data) return -ENOMEM; for (i = 0; i < pdata->num_leds; i++) { cur_led = &pdata->leds[i]; led_dat = &leds_data[i]; printk("[LED] %s hw_revision=%d \n", __func__, hw_revision); if(hw_revision < 3 ) { vmmc2 = regulator_get( &pdev->dev, "vmmc2" ); if( IS_ERR( vmmc2 ) ) { printk("PSENSOR: %s: regulator_get failed to get vmmc2!\n", __func__); goto err; } } else { ret = gpio_request(OMAP_GPIO_LED_EN, cur_led->name); if (ret < 0) goto err; led_dat->gpio = OMAP_GPIO_LED_EN; led_dat->can_sleep = gpio_cansleep(OMAP_GPIO_LED_EN); gpio_direction_output(OMAP_GPIO_LED_EN, 1); ret = twl_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00, TWL4030_VMMC2_DEV_GRP); if (ret) printk(" leds-archer.c fail to set reousrce off TWL4030_VMMC2_DEV_GRP\n"); } led_dat->cdev.name = cur_led->name; led_dat->cdev.default_trigger = cur_led->default_trigger; led_dat->cdev.brightness_set = archer_led_set; led_dat->cdev.brightness = LED_OFF; led_dat->cdev.flags |= LED_CORE_SUSPENDRESUME; // gpio_direction_output(led_dat->gpio, led_dat->active_low); // INIT_WORK(&led_dat->work, gpio_led_work); ret = led_classdev_register(&pdev->dev, &led_dat->cdev); if (ret < 0) { // gpio_free(led_dat->gpio); regulator_put( vmmc2 ); goto err; } } platform_set_drvdata(pdev, leds_data); return 0; err: if (i > 0) { for (i = i - 1; i >= 0; i--) { led_classdev_unregister(&leds_data[i].cdev); // cancel_work_sync(&leds_data[i].work); // gpio_free(leds_data[i].gpio); } } kfree(leds_data); return ret; }
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs, struct gpio_event_info *info, void **data, int func) { int i; int err; int key_count; int phone_call_status; int fm_radio_status; int irq; static int irq_status = 1; struct gpio_kp *kp; struct gpio_event_matrix_info *mi; mi = container_of(info, struct gpio_event_matrix_info, info); if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) { /* TODO: disable scanning */ if (mi->detect_phone_status == 0) { if (func == GPIO_EVENT_FUNC_SUSPEND) irq_status = 0; else irq_status = 1; } else { phone_call_status = gpio_event_get_phone_call_status() & 0x01; fm_radio_status = gpio_event_get_fm_radio_status() & 0x01; KEY_LOGI("%s: mi->ninputs: %d, func&0x01 = %d, phone_call_status=%d, fm_radio_status=%d\n", __func__, mi->ninputs, func & 0x01, phone_call_status, fm_radio_status); if (irq_status != ((func & 0x01) | phone_call_status | fm_radio_status)) { irq_status = ((func & 0x01) | phone_call_status | fm_radio_status); KEY_LOGI("%s: irq_status %d \n", __func__, irq_status); } else { KEY_LOGI("%s: irq_status %d, did not change\n", __func__, irq_status); return 0; } } for (i = 0; i < mi->ninputs; i++) { irq = gpio_to_irq(mi->input_gpios[i]); err = irq_set_irq_wake(irq, irq_status); if (err) KEY_LOGE("gpiomatrix: set_irq_wake failed ,irq_status %d ,for input irq %d,%d\n", irq_status, i, irq); else KEY_LOGD("%s: set ok,irq_status %d, irq %d = %d\n", __func__, irq_status, i, irq); } return 0; } if (func == GPIO_EVENT_FUNC_INIT) { if (mi->keymap == NULL || mi->input_gpios == NULL || mi->output_gpios == NULL) { err = -ENODEV; KEY_LOGE("gpiomatrix: Incomplete pdata\n"); goto err_invalid_platform_data; } key_count = mi->ninputs * mi->noutputs; *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) * BITS_TO_LONGS(key_count), GFP_KERNEL); if (kp == NULL) { err = -ENOMEM; KEY_LOGE("gpiomatrix: Failed to allocate private data\n"); goto err_kp_alloc_failed; } kp->input_devs = input_devs; kp->keypad_info = mi; for (i = 0; i < key_count; i++) { unsigned short keyentry = mi->keymap[i]; unsigned short keycode = keyentry & MATRIX_KEY_MASK; unsigned short dev = keyentry >> MATRIX_CODE_BITS; if (dev >= input_devs->count) { KEY_LOGE("gpiomatrix: bad device index %d >= " "%d for key code %d\n", dev, input_devs->count, keycode); err = -EINVAL; goto err_bad_keymap; } if (keycode && keycode <= KEY_MAX) input_set_capability(input_devs->dev[dev], EV_KEY, keycode); } #ifndef CONFIG_ARCH_MSM8X60 if (mi->setup_ninputs_gpio) mi->setup_ninputs_gpio(); #else if (mi->setup_matrix_gpio) mi->setup_matrix_gpio(); #endif for (i = 0; i < mi->noutputs; i++) { err = gpio_request(mi->output_gpios[i], "gpio_kp_out"); if (err) { KEY_LOGE("gpiomatrix: gpio_request failed for " "output %d\n", mi->output_gpios[i]); goto err_request_output_gpio_failed; } if (gpio_cansleep(mi->output_gpios[i])) { KEY_LOGE("gpiomatrix: unsupported output gpio %d," " can sleep\n", mi->output_gpios[i]); err = -EINVAL; goto err_output_gpio_configure_failed; } if (mi->flags & GPIOKPF_DRIVE_INACTIVE) err = gpio_direction_output(mi->output_gpios[i], !(mi->flags & GPIOKPF_ACTIVE_HIGH)); else err = gpio_direction_input(mi->output_gpios[i]); if (err) { KEY_LOGE("gpiomatrix: gpio_configure failed for " "output %d\n", mi->output_gpios[i]); goto err_output_gpio_configure_failed; } } for (i = 0; i < mi->ninputs; i++) { err = gpio_request(mi->input_gpios[i], "gpio_kp_in"); if (err) { KEY_LOGE("gpiomatrix: gpio_request failed for " "input %d\n", mi->input_gpios[i]); goto err_request_input_gpio_failed; } err = gpio_direction_input(mi->input_gpios[i]); if (err) { KEY_LOGE("gpiomatrix: gpio_direction_input failed" " for input %d\n", mi->input_gpios[i]); goto err_gpio_direction_input_failed; } } kp->current_output = mi->noutputs; kp->key_state_changed = 1; #ifndef CONFIG_ARCH_MSM8X60 hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); kp->timer.function = gpio_keypad_timer_func; #else km_queue = create_singlethread_workqueue("km_queue"); INIT_WORK(&kp->work, gpio_keypad_timer_func); #endif wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp"); err = gpio_keypad_request_irqs(kp); kp->use_irq = err == 0; #ifndef CONFIG_ARCH_MSM8X60 kp_use_irq = kp->use_irq; #endif KEY_LOGI("GPIO Matrix Keypad Driver: Start keypad matrix for " "%s%s in %s mode\n", input_devs->dev[0]->name, (input_devs->count > 1) ? "..." : "", kp->use_irq ? "interrupt" : "polling"); if (kp->use_irq) wake_lock(&kp->wake_lock); #ifndef CONFIG_ARCH_MSM8X60 hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL); #else queue_work(km_queue, &kp->work); #endif return 0; } err = 0; kp = *data; if (kp->use_irq) for (i = mi->noutputs - 1; i >= 0; i--) free_irq(gpio_to_irq(mi->input_gpios[i]), kp); #ifndef CONFIG_ARCH_MSM8X60 hrtimer_cancel(&kp->timer); #else cancel_work_sync(&kp->work); #endif wake_lock_destroy(&kp->wake_lock); for (i = mi->noutputs - 1; i >= 0; i--) { err_gpio_direction_input_failed: gpio_free(mi->input_gpios[i]); err_request_input_gpio_failed: ; } for (i = mi->noutputs - 1; i >= 0; i--) { err_output_gpio_configure_failed: gpio_free(mi->output_gpios[i]); err_request_output_gpio_failed: ; } err_bad_keymap: kfree(kp); err_kp_alloc_failed: err_invalid_platform_data: return err; }