static int __devinit w90p910_keypad_probe(struct platform_device *pdev) { const struct w90p910_keypad_platform_data *pdata = pdev->dev.platform_data; const struct matrix_keymap_data *keymap_data; struct w90p910_keypad *keypad; struct input_dev *input_dev; struct resource *res; int irq; int error; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } keymap_data = pdata->keymap_data; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get keypad irq\n"); return -ENXIO; } keypad = kzalloc(sizeof(struct w90p910_keypad), GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !input_dev) { dev_err(&pdev->dev, "failed to allocate driver data\n"); error = -ENOMEM; goto failed_free; } keypad->pdata = pdata; keypad->input_dev = input_dev; keypad->irq = irq; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "failed to get I/O memory\n"); error = -ENXIO; goto failed_free; } res = request_mem_region(res->start, resource_size(res), pdev->name); if (res == NULL) { dev_err(&pdev->dev, "failed to request I/O memory\n"); error = -EBUSY; goto failed_free; } keypad->mmio_base = ioremap(res->start, resource_size(res)); if (keypad->mmio_base == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; goto failed_free_res; } keypad->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clock\n"); error = PTR_ERR(keypad->clk); goto failed_free_io; } /* set multi-function pin for w90p910 kpi. */ mfp_set_groupi(&pdev->dev); input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->open = w90p910_keypad_open; input_dev->close = w90p910_keypad_close; input_dev->dev.parent = &pdev->dev; input_dev->keycode = keypad->keymap; input_dev->keycodesize = sizeof(keypad->keymap[0]); input_dev->keycodemax = ARRAY_SIZE(keypad->keymap); input_set_drvdata(input_dev, keypad); input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); input_set_capability(input_dev, EV_MSC, MSC_SCAN); matrix_keypad_build_keymap(keymap_data, W90P910_ROW_SHIFT, input_dev->keycode, input_dev->keybit); error = request_irq(keypad->irq, w90p910_keypad_irq_handler, IRQF_DISABLED, pdev->name, keypad); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); goto failed_put_clk; } /* Register the input device */ error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); goto failed_free_irq; } platform_set_drvdata(pdev, keypad); return 0; failed_free_irq: free_irq(irq, pdev); failed_put_clk: clk_put(keypad->clk); failed_free_io: iounmap(keypad->mmio_base); failed_free_res: release_mem_region(res->start, resource_size(res)); failed_free: input_free_device(input_dev); kfree(keypad); return error; }
static int imx_keypad_probe(struct platform_device *pdev) { const struct matrix_keymap_data *keymap_data = dev_get_platdata(&pdev->dev); struct imx_keypad *keypad; struct input_dev *input_dev; struct resource *res; int irq, error, i, row, col; if (!keymap_data && !pdev->dev.of_node) { dev_err(&pdev->dev, "no keymap defined\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq defined in platform data\n"); return irq; } input_dev = devm_input_allocate_device(&pdev->dev); if (!input_dev) { dev_err(&pdev->dev, "failed to allocate the input device\n"); return -ENOMEM; } keypad = devm_kzalloc(&pdev->dev, sizeof(struct imx_keypad), GFP_KERNEL); if (!keypad) { dev_err(&pdev->dev, "not enough memory for driver data\n"); return -ENOMEM; } keypad->input_dev = input_dev; keypad->irq = irq; keypad->stable_count = 0; setup_timer(&keypad->check_matrix_timer, imx_keypad_check_for_events, (unsigned long) keypad); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); keypad->mmio_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(keypad->mmio_base)) return PTR_ERR(keypad->mmio_base); keypad->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clock\n"); return PTR_ERR(keypad->clk); } /* Init the Input device */ input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->open = imx_keypad_open; input_dev->close = imx_keypad_close; error = matrix_keypad_build_keymap(keymap_data, NULL, MAX_MATRIX_KEY_ROWS, MAX_MATRIX_KEY_COLS, keypad->keycodes, input_dev); if (error) { dev_err(&pdev->dev, "failed to build keymap\n"); return error; } /* Search for rows and cols enabled */ for (row = 0; row < MAX_MATRIX_KEY_ROWS; row++) { for (col = 0; col < MAX_MATRIX_KEY_COLS; col++) { i = MATRIX_SCAN_CODE(row, col, MATRIX_ROW_SHIFT); if (keypad->keycodes[i] != KEY_RESERVED) { keypad->rows_en_mask |= 1 << row; keypad->cols_en_mask |= 1 << col; } } } dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); /* Ensure that the keypad will stay dormant until opened */ clk_prepare_enable(keypad->clk); imx_keypad_inhibit(keypad); clk_disable_unprepare(keypad->clk); error = devm_request_irq(&pdev->dev, irq, imx_keypad_irq_handler, 0, pdev->name, keypad); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); return error; } /* Register the input device */ error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); return error; } platform_set_drvdata(pdev, keypad); device_init_wakeup(&pdev->dev, 1); return 0; }
static int tca8418_keypad_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct device *dev = &client->dev; const struct tca8418_keypad_platform_data *pdata = dev_get_platdata(dev); struct tca8418_keypad *keypad_data; struct input_dev *input; const struct matrix_keymap_data *keymap_data = NULL; u32 rows = 0, cols = 0; bool rep = false; bool irq_is_gpio = false; int irq; int error, row_shift, max_keys; /* Copy the platform data */ if (pdata) { if (!pdata->keymap_data) { dev_err(dev, "no keymap data defined\n"); return -EINVAL; } keymap_data = pdata->keymap_data; rows = pdata->rows; cols = pdata->cols; rep = pdata->rep; irq_is_gpio = pdata->irq_is_gpio; } else { struct device_node *np = dev->of_node; int err; err = matrix_keypad_parse_of_params(dev, &rows, &cols); if (err) return err; rep = of_property_read_bool(np, "keypad,autorepeat"); } if (!rows || rows > TCA8418_MAX_ROWS) { dev_err(dev, "invalid rows\n"); return -EINVAL; } if (!cols || cols > TCA8418_MAX_COLS) { dev_err(dev, "invalid columns\n"); return -EINVAL; } /* Check i2c driver capabilities */ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE)) { dev_err(dev, "%s adapter not supported\n", dev_driver_string(&client->adapter->dev)); return -ENODEV; } row_shift = get_count_order(cols); max_keys = rows << row_shift; /* Allocate memory for keypad_data and input device */ keypad_data = devm_kzalloc(dev, sizeof(*keypad_data), GFP_KERNEL); if (!keypad_data) return -ENOMEM; keypad_data->client = client; keypad_data->row_shift = row_shift; /* Initialize the chip or fail if chip isn't present */ error = tca8418_configure(keypad_data, rows, cols); if (error < 0) return error; /* Configure input device */ input = devm_input_allocate_device(dev); if (!input) return -ENOMEM; keypad_data->input = input; input->name = client->name; input->id.bustype = BUS_I2C; input->id.vendor = 0x0001; input->id.product = 0x001; input->id.version = 0x0001; error = matrix_keypad_build_keymap(keymap_data, NULL, rows, cols, NULL, input); if (error) { dev_err(dev, "Failed to build keymap\n"); return error; } if (rep) __set_bit(EV_REP, input->evbit); input_set_capability(input, EV_MSC, MSC_SCAN); input_set_drvdata(input, keypad_data); irq = client->irq; if (irq_is_gpio) irq = gpio_to_irq(irq); error = devm_request_threaded_irq(dev, irq, NULL, tca8418_irq_handler, IRQF_TRIGGER_FALLING | IRQF_SHARED | IRQF_ONESHOT, client->name, keypad_data); if (error) { dev_err(dev, "Unable to claim irq %d; error %d\n", client->irq, error); return error; } error = input_register_device(input); if (error) { dev_err(dev, "Unable to register input device, error: %d\n", error); return error; } return 0; }
static int __devinit omap_kp_probe(struct platform_device *pdev) { struct omap_kp *omap_kp; struct input_dev *input_dev; struct omap_kp_platform_data *pdata = pdev->dev.platform_data; int i, col_idx, row_idx, irq_idx, ret; unsigned int row_shift, keycodemax; if (!pdata->rows || !pdata->cols || !pdata->keymap_data) { printk(KERN_ERR "No rows, cols or keymap_data from pdata\n"); return -EINVAL; } row_shift = get_count_order(pdata->cols); keycodemax = pdata->rows << row_shift; omap_kp = kzalloc(sizeof(struct omap_kp) + keycodemax * sizeof(unsigned short), GFP_KERNEL); input_dev = input_allocate_device(); if (!omap_kp || !input_dev) { kfree(omap_kp); input_free_device(input_dev); return -ENOMEM; } platform_set_drvdata(pdev, omap_kp); omap_kp->input = input_dev; /* Disable the interrupt for the MPUIO keyboard */ if (!cpu_is_omap24xx()) omap_writew(1, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); input_dev->keycode = &omap_kp[1]; input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodemax = keycodemax; if (pdata->rep) __set_bit(EV_REP, input_dev->evbit); if (pdata->delay) omap_kp->delay = pdata->delay; if (pdata->row_gpios && pdata->col_gpios) { row_gpios = pdata->row_gpios; col_gpios = pdata->col_gpios; } omap_kp->rows = pdata->rows; omap_kp->cols = pdata->cols; if (cpu_is_omap24xx()) { /* Cols: outputs */ for (col_idx = 0; col_idx < omap_kp->cols; col_idx++) { if (gpio_request(col_gpios[col_idx], "omap_kp_col") < 0) { printk(KERN_ERR "Failed to request" "GPIO%d for keypad\n", col_gpios[col_idx]); goto err1; } gpio_direction_output(col_gpios[col_idx], 0); } /* Rows: inputs */ for (row_idx = 0; row_idx < omap_kp->rows; row_idx++) { if (gpio_request(row_gpios[row_idx], "omap_kp_row") < 0) { printk(KERN_ERR "Failed to request" "GPIO%d for keypad\n", row_gpios[row_idx]); goto err2; } gpio_direction_input(row_gpios[row_idx]); } } else { col_idx = 0; row_idx = 0; } setup_timer(&omap_kp->timer, omap_kp_timer, (unsigned long)omap_kp); /* get the irq and init timer*/ tasklet_enable(&kp_tasklet); kp_tasklet.data = (unsigned long) omap_kp; ret = device_create_file(&pdev->dev, &dev_attr_enable); if (ret < 0) goto err2; /* setup input device */ __set_bit(EV_KEY, input_dev->evbit); matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input_dev->keycode, input_dev->keybit); input_dev->name = "omap-keypad"; input_dev->phys = "omap-keypad/input0"; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; ret = input_register_device(omap_kp->input); if (ret < 0) { printk(KERN_ERR "Unable to register omap-keypad input device\n"); goto err3; } if (pdata->dbounce) omap_writew(0xff, OMAP1_MPUIO_BASE + OMAP_MPUIO_GPIO_DEBOUNCING); /* scan current status and enable interrupt */ omap_kp_scan_keypad(omap_kp, keypad_state); if (!cpu_is_omap24xx()) { omap_kp->irq = platform_get_irq(pdev, 0); if (omap_kp->irq >= 0) { if (request_irq(omap_kp->irq, omap_kp_interrupt, 0, "omap-keypad", omap_kp) < 0) goto err4; } omap_writew(0, OMAP1_MPUIO_BASE + OMAP_MPUIO_KBD_MASKIT); } else { for (irq_idx = 0; irq_idx < omap_kp->rows; irq_idx++) { if (request_irq(gpio_to_irq(row_gpios[irq_idx]), omap_kp_interrupt, IRQF_TRIGGER_FALLING, "omap-keypad", omap_kp) < 0) goto err5; } } return 0; err5: for (i = irq_idx - 1; i >=0; i--) free_irq(row_gpios[i], omap_kp); err4: input_unregister_device(omap_kp->input); input_dev = NULL; err3: device_remove_file(&pdev->dev, &dev_attr_enable); err2: for (i = row_idx - 1; i >=0; i--) gpio_free(row_gpios[i]); err1: for (i = col_idx - 1; i >=0; i--) gpio_free(col_gpios[i]); kfree(omap_kp); input_free_device(input_dev); return -EINVAL; }
static int matrix_keypad_probe(struct platform_device *pdev) { struct matrix_keypad_platform_data *pdata; struct matrix_keypad *keypad; struct input_dev *input_dev; #ifdef CONFIG_SUPPORT_KEYPAD_LED struct device *sec_keypad; #endif int err; pdata = dev_get_platdata(&pdev->dev); if (!pdata) { pdata = matrix_keypad_parse_dt(&pdev->dev); if (IS_ERR(pdata)) { dev_err(&pdev->dev, "no platform data defined\n"); return PTR_ERR(pdata); } } else if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !input_dev) { err = -ENOMEM; goto err_free_mem; } keypad->input_dev = input_dev; keypad->pdata = pdata; keypad->row_shift = get_count_order(pdata->num_col_gpios); keypad->stopped = true; INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); spin_lock_init(&keypad->lock); if (pdata->project) input_dev->name = pdata->project; else input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->open = matrix_keypad_start; input_dev->close = matrix_keypad_stop; err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, pdata->num_row_gpios, pdata->num_col_gpios, NULL, input_dev); if (err) { dev_err(&pdev->dev, "failed to build keymap\n"); goto err_free_mem; } if (!pdata->no_autorepeat) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); err = matrix_keypad_init_gpio(pdev, keypad); if (err) goto err_free_mem; err = input_register_device(keypad->input_dev); if (err) goto err_free_gpio; #ifdef CONFIG_SUPPORT_KEYPAD_LED /* keypad led control */ sec_keypad = sec_device_create(pdata, "sec_keypad"); if (IS_ERR(sec_keypad)) dev_err(&pdev->dev,"Failed to create device(sec_key)!\n"); err = device_create_file(sec_keypad, &dev_attr_brightness); if (err) { dev_err(&pdev->dev,"Failed to create device file in sysfs entries(%s)!\n", dev_attr_brightness.attr.name); } dev_set_drvdata(sec_keypad, pdata); pdata->vddo_vreg = regulator_get(&pdev->dev,"vddo"); if (IS_ERR(pdata->vddo_vreg)){ pdata->vddo_vreg = NULL; printk(KERN_INFO "pdata->vddo_vreg error\n"); err = -EPERM; goto err_free_gpio; } #endif device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_gpio: matrix_keypad_free_gpio(keypad); err_free_mem: input_free_device(input_dev); kfree(keypad); return err; }
static int __devinit matrix_keypad_probe(struct platform_device *pdev) { const struct matrix_keypad_platform_data *pdata; const struct matrix_keymap_data *keymap_data; struct matrix_keypad *keypad; struct input_dev *input_dev; unsigned short *keycodes; unsigned int row_shift; int err; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } row_shift = get_count_order(pdata->num_col_gpios); keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); keycodes = kzalloc((pdata->num_row_gpios << row_shift) * sizeof(*keycodes), GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !keycodes || !input_dev) { err = -ENOMEM; goto err_free_mem; } keypad->input_dev = input_dev; keypad->pdata = pdata; keypad->keycodes = keycodes; keypad->row_shift = row_shift; keypad->stopped = true; INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); mutex_init(&keypad->lock); input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->evbit[0] = BIT_MASK(EV_KEY); if (!pdata->no_autorepeat) input_dev->evbit[0] |= BIT_MASK(EV_REP); input_dev->open = matrix_keypad_start; input_dev->close = matrix_keypad_stop; input_dev->keycode = keycodes; input_dev->keycodesize = sizeof(*keycodes); input_dev->keycodemax = pdata->num_row_gpios << row_shift; matrix_keypad_build_keymap(keymap_data, row_shift, input_dev->keycode, input_dev->keybit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); err = init_matrix_gpio(pdev, keypad); if (err) goto err_free_mem; err = input_register_device(keypad->input_dev); if (err) goto err_free_mem; device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_mem: input_free_device(input_dev); kfree(keycodes); kfree(keypad); return err; }
static int __devinit ske_keypad_probe(struct platform_device *pdev) { const struct ske_keypad_platform_data *plat = pdev->dev.platform_data; struct ske_keypad *keypad; struct input_dev *input; struct resource *res; int irq; int error; if (!plat) { dev_err(&pdev->dev, "invalid keypad platform data\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get keypad irq\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "missing platform resources\n"); return -EINVAL; } keypad = kzalloc(sizeof(struct ske_keypad), GFP_KERNEL); input = input_allocate_device(); if (!keypad || !input) { dev_err(&pdev->dev, "failed to allocate keypad memory\n"); error = -ENOMEM; goto err_free_mem; } keypad->irq = irq; keypad->board = plat; keypad->input = input; spin_lock_init(&keypad->ske_keypad_lock); if (!request_mem_region(res->start, resource_size(res), pdev->name)) { dev_err(&pdev->dev, "failed to request I/O memory\n"); error = -EBUSY; goto err_free_mem; } keypad->reg_base = ioremap(res->start, resource_size(res)); if (!keypad->reg_base) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENXIO; goto err_free_mem_region; } keypad->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get clk\n"); error = PTR_ERR(keypad->clk); goto err_iounmap; } input->id.bustype = BUS_HOST; input->name = "ux500-ske-keypad"; input->dev.parent = &pdev->dev; input->keycode = keypad->keymap; input->keycodesize = sizeof(keypad->keymap[0]); input->keycodemax = ARRAY_SIZE(keypad->keymap); input_set_capability(input, EV_MSC, MSC_SCAN); __set_bit(EV_KEY, input->evbit); if (!plat->no_autorepeat) __set_bit(EV_REP, input->evbit); matrix_keypad_build_keymap(plat->keymap_data, SKE_KEYPAD_ROW_SHIFT, input->keycode, input->keybit); clk_enable(keypad->clk); /* go through board initialization helpers */ if (keypad->board->init) keypad->board->init(); error = ske_keypad_chip_init(keypad); if (error) { dev_err(&pdev->dev, "unable to init keypad hardware\n"); goto err_clk_disable; } error = request_threaded_irq(keypad->irq, NULL, ske_keypad_irq, IRQF_ONESHOT, "ske-keypad", keypad); if (error) { dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq); goto err_clk_disable; } error = input_register_device(input); if (error) { dev_err(&pdev->dev, "unable to register input device: %d\n", error); goto err_free_irq; } if (plat->wakeup_enable) device_init_wakeup(&pdev->dev, true); platform_set_drvdata(pdev, keypad); return 0; err_free_irq: free_irq(keypad->irq, keypad); err_clk_disable: clk_disable(keypad->clk); clk_put(keypad->clk); err_iounmap: iounmap(keypad->reg_base); err_free_mem_region: release_mem_region(res->start, resource_size(res)); err_free_mem: input_free_device(input); kfree(keypad); return error; }
static int __devinit sci_keypad_probe(struct platform_device *pdev) { struct sci_keypad_t *sci_kpd; struct input_dev *input_dev; struct sci_keypad_platform_data *pdata = pdev->dev.platform_data; int error; unsigned long value; unsigned int row_shift, keycodemax; row_shift = get_count_order(pdata->cols); keycodemax = pdata->rows << row_shift; sci_kpd = kzalloc(sizeof(struct sci_keypad_t) + keycodemax * sizeof(unsigned short), GFP_KERNEL); input_dev = input_allocate_device(); if (!sci_kpd || !input_dev) { kfree(sci_kpd); input_free_device(input_dev); return -ENOMEM; } platform_set_drvdata(pdev, sci_kpd); sci_kpd->input_dev = input_dev; sci_kpd->rows = pdata->rows; sci_kpd->cols = pdata->cols; sci_glb_set(REG_GLB_SOFT_RST,BIT_KPD_RST); mdelay(2); sci_glb_clr(REG_GLB_SOFT_RST,BIT_KPD_RST); sci_glb_set(REG_GLB_GEN0,BIT_KPD_EB | BIT_RTC_KPD_EB); keypad_writel(KPD_INT_CLR, KPD_INT_ALL); value = CFG_ROW_POLARITY | CFG_COL_POLARITY; keypad_writel(KPD_POLARITY, value); keypad_writel(KPD_CLK_DIV_CNT, 1); keypad_writel(KPD_LONG_KEY_CNT, 0xc); keypad_writel(KPD_DEBOUNCE_CNT, 0x5); sci_kpd->irq = platform_get_irq(pdev, 0); if (sci_kpd->irq < 0) { error = -ENODEV; dev_err(&pdev->dev, "Get irq number error,Keypad Module\n"); goto out2; } error = request_irq(sci_kpd->irq, sci_keypad_isr, 0, "sci-keypad", sci_kpd); if (error) { dev_err(&pdev->dev, "unable to claim irq %d\n", sci_kpd->irq); goto out2; } input_dev->name = pdev->name; input_dev->phys = "sci-key/input0"; input_dev->dev.parent = &pdev->dev; input_set_drvdata(input_dev, sci_kpd); input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->keycode = &sci_kpd[1]; input_dev->keycodesize = sizeof(unsigned short); input_dev->keycodemax = keycodemax; matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input_dev->keycode, input_dev->keybit); /* there are keys from hw other than keypad controller */ __set_bit(KEY_POWER, input_dev->keybit); __set_bit(EV_KEY, input_dev->evbit); if (pdata->repeat) __set_bit(EV_REP, input_dev->evbit); error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "unable to register input device\n"); goto out4; } device_init_wakeup(&pdev->dev, 1); value = KPD_INT_DOWNUP; if (pdata->support_long_key) value |= KPD_INT_LONG; keypad_writel(KPD_INT_EN, value); value = KPD_SLEEP_CNT_VALUE(1000); keypad_writel(KPD_SLEEP_CNT, value); value = KPD_SLEEP_EN | (pdata->rows_choose_hw & KPDCTL_ROW_MSK) | (pdata->cols_choose_hw & KPDCTL_COL_MSK); if (pdata->support_long_key) value |= KPD_LONG_KEY_EN; value |= KPD_EN; keypad_writel(KPD_CTRL, value); gpio_request(ANA_GPI_PB, "powerkey"); gpio_direction_input(ANA_GPI_PB); error = request_irq(gpio_to_irq(ANA_GPI_PB), sci_powerkey_isr, IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND, "powerkey", sci_kpd); if (error) { dev_err(&pdev->dev, "unable to claim irq %d\n", gpio_to_irq(ANA_GPI_PB)); goto out2; } dump_keypad_register(); return 0; out4: input_free_device(input_dev); free_irq(sci_kpd->irq, pdev); out2: kfree(sci_kpd); platform_set_drvdata(pdev, NULL); return error; }
static int __devinit omap4_keypad_probe(struct platform_device *pdev) { const struct omap4_keypad_platform_data *pdata; struct omap4_keypad *keypad_data; struct input_dev *input_dev; struct resource *res; resource_size_t size; unsigned int row_shift, max_keys; int rev; int irq; int error; /* platform data */ pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no base address specified\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "no keyboard irq assigned\n"); return -EINVAL; } if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } row_shift = get_count_order(pdata->cols); max_keys = pdata->rows << row_shift; keypad_data = kzalloc(sizeof(struct omap4_keypad) + max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL); if (!keypad_data) { dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); return -ENOMEM; } size = resource_size(res); res = request_mem_region(res->start, size, pdev->name); if (!res) { dev_err(&pdev->dev, "can't request mem region\n"); error = -EBUSY; goto err_free_keypad; } keypad_data->base = ioremap(res->start, resource_size(res)); if (!keypad_data->base) { dev_err(&pdev->dev, "can't ioremap mem resource\n"); error = -ENOMEM; goto err_release_mem; } keypad_data->irq = irq; keypad_data->row_shift = row_shift; keypad_data->rows = pdata->rows; keypad_data->cols = pdata->cols; /* * Enable clocks for the keypad module so that we can read * revision register. */ pm_runtime_enable(&pdev->dev); error = pm_runtime_get_sync(&pdev->dev); if (error) { dev_err(&pdev->dev, "pm_runtime_get_sync() failed\n"); goto err_unmap; } rev = __raw_readl(keypad_data->base + OMAP4_KBD_REVISION); rev &= 0x03 << 30; rev >>= 30; switch (rev) { case KBD_REVISION_OMAP4: keypad_data->reg_offset = 0x00; keypad_data->irqreg_offset = 0x00; break; case KBD_REVISION_OMAP5: keypad_data->reg_offset = 0x10; keypad_data->irqreg_offset = 0x0c; break; default: dev_err(&pdev->dev, "Keypad reports unsupported revision %d", rev); error = -EINVAL; goto err_pm_put_sync; } /* input device allocation */ keypad_data->input = input_dev = input_allocate_device(); if (!input_dev) { error = -ENOMEM; goto err_pm_put_sync; } input_dev->name = pdev->name; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0001; input_dev->open = omap4_keypad_open; input_dev->close = omap4_keypad_close; error = matrix_keypad_build_keymap(pdata->keymap_data, NULL, pdata->rows, pdata->cols, keypad_data->keymap, input_dev); if (error) { dev_err(&pdev->dev, "failed to build keymap\n"); goto err_free_input; } __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad_data); error = request_irq(keypad_data->irq, omap4_keypad_interrupt, IRQF_TRIGGER_RISING, "omap4-keypad", keypad_data); if (error) { dev_err(&pdev->dev, "failed to register interrupt\n"); goto err_free_input; } pm_runtime_put_sync(&pdev->dev); error = input_register_device(keypad_data->input); if (error < 0) { dev_err(&pdev->dev, "failed to register input device\n"); goto err_pm_disable; } platform_set_drvdata(pdev, keypad_data); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); free_irq(keypad_data->irq, keypad_data); err_free_input: input_free_device(input_dev); err_pm_put_sync: pm_runtime_put_sync(&pdev->dev); err_unmap: iounmap(keypad_data->base); err_release_mem: release_mem_region(res->start, size); err_free_keypad: kfree(keypad_data); return error; }
static int __devinit spear_kbd_probe(struct platform_device *pdev) { const struct kbd_platform_data *pdata = pdev->dev.platform_data; const struct matrix_keymap_data *keymap; struct spear_kbd *kbd; struct input_dev *input_dev; struct resource *res; int irq; int error; if (!pdata) { dev_err(&pdev->dev, "Invalid platform data\n"); return -EINVAL; } keymap = pdata->keymap; if (!keymap) { dev_err(&pdev->dev, "no keymap defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no keyboard resource defined\n"); return -EBUSY; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "not able to get irq for the device\n"); return irq; } kbd = kzalloc(sizeof(*kbd), GFP_KERNEL); input_dev = input_allocate_device(); if (!kbd || !input_dev) { dev_err(&pdev->dev, "out of memory\n"); error = -ENOMEM; goto err_free_mem; } kbd->input = input_dev; kbd->irq = irq; kbd->res = request_mem_region(res->start, resource_size(res), pdev->name); if (!kbd->res) { dev_err(&pdev->dev, "keyboard region already claimed\n"); error = -EBUSY; goto err_free_mem; } kbd->io_base = ioremap(res->start, resource_size(res)); if (!kbd->io_base) { dev_err(&pdev->dev, "ioremap failed for kbd_region\n"); error = -ENOMEM; goto err_release_mem_region; } kbd->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(kbd->clk)) { error = PTR_ERR(kbd->clk); goto err_iounmap; } input_dev->name = "Spear Keyboard"; input_dev->phys = "keyboard/input0"; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->open = spear_kbd_open; input_dev->close = spear_kbd_close; __set_bit(EV_KEY, input_dev->evbit); if (pdata->rep) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_dev->keycode = kbd->keycodes; input_dev->keycodesize = sizeof(kbd->keycodes[0]); input_dev->keycodemax = ARRAY_SIZE(kbd->keycodes); matrix_keypad_build_keymap(keymap, ROW_SHIFT, input_dev->keycode, input_dev->keybit); input_set_drvdata(input_dev, kbd); error = request_irq(irq, spear_kbd_interrupt, 0, "keyboard", kbd); if (error) { dev_err(&pdev->dev, "request_irq fail\n"); goto err_put_clk; } error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "Unable to register keyboard device\n"); goto err_free_irq; } device_init_wakeup(&pdev->dev, 1); platform_set_drvdata(pdev, kbd); return 0; err_free_irq: free_irq(kbd->irq, kbd); err_put_clk: clk_put(kbd->clk); err_iounmap: iounmap(kbd->io_base); err_release_mem_region: release_mem_region(res->start, resource_size(res)); err_free_mem: input_free_device(input_dev); kfree(kbd); return error; }
/****************************************************************************** * struct platform_driver functions *****************************************************************************/ static int __devinit ftkbc010_probe(struct platform_device *pdev) { struct matrix_keypad_platform_data *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct ftkbc010 *ftkbc010; struct input_dev *input; struct resource *res; unsigned int row_shift, max_keys; int irq; int ret; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(dev, "No mmio resource defined.\n"); return -ENXIO; } if ((irq = platform_get_irq(pdev, 0)) < 0) { dev_err(dev, "No irq resource defined.\n"); ret = irq; goto err_get_irq; } /* * Allocate driver private data */ ftkbc010 = kzalloc(sizeof(struct ftkbc010), GFP_KERNEL); if (!ftkbc010) { dev_err(dev, "Failed to allocate memory.\n"); ret = -ENOMEM; goto err_alloc_priv; } platform_set_drvdata(pdev, ftkbc010); /* * Allocate input_dev */ input = input_allocate_device(); if (!input) { dev_err(dev, "Failed to allocate input device.\n"); ret = -EBUSY; goto err_alloc_input_dev; } ftkbc010->input = input; /* * Map io memory */ ftkbc010->res = request_mem_region(res->start, resource_size(res), dev_name(dev)); if (!ftkbc010->res) { dev_err(dev, "Resources is unavailable.\n"); ret = -EBUSY; goto err_req_mem_region; } ftkbc010->base = ioremap(res->start, resource_size(res)); if (!ftkbc010->base) { dev_err(dev, "Failed to map registers.\n"); ret = -ENOMEM; goto err_ioremap; } ret = request_irq(irq, ftkbc010_interrupt, 0, pdev->name, ftkbc010); if (ret < 0) { dev_err(dev, "Failed to request irq %d\n", irq); goto err_req_irq; } ftkbc010->irq = irq; row_shift = get_count_order(pdata->num_col_gpios); max_keys = pdata->num_row_gpios << row_shift; ftkbc010->rows = pdata->num_row_gpios; ftkbc010->cols = pdata->num_col_gpios; ftkbc010->row_shift = row_shift; input->name = "Faraday keyboard controller"; input->keycode = ftkbc010->keycode; input->keycodesize = sizeof(ftkbc010->keycode[0]); input->keycodemax = max_keys; /* * Declare what events and event codes can be generated */ input->evbit[0] = BIT_MASK(EV_KEY); matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input->keycode, input->keybit); /* * Enable hardware */ ftkbc010_enable(ftkbc010); /* * All went ok, so register to the input system */ ret = input_register_device(input); if (ret) goto err_register_input; dev_info(dev, "irq %d, mapped at %p\n", irq, ftkbc010->base); return 0; err_register_input: free_irq(irq, ftkbc010); err_req_irq: iounmap(ftkbc010->base); err_ioremap: release_mem_region(res->start, resource_size(res)); err_req_mem_region: input_free_device(ftkbc010->input); err_alloc_input_dev: platform_set_drvdata(pdev, NULL); kfree(ftkbc010); err_alloc_priv: err_get_irq: release_resource(res); return ret; }
/* Interrupt handler */ static irqreturn_t omap4_keypad_interrupt(int irq, void *dev_id) { struct omap4_keypad *keypad_data = dev_id; struct input_dev *input_dev = keypad_data->input; unsigned char key_state[ARRAY_SIZE(keypad_data->key_state)]; unsigned int col, row, code, changed; u32 *new_state = (u32 *) key_state; /* LGE_SJIT 2012-01-05 [[email protected]] wake lock from P940 GB * 2011.12.07 [email protected] For Volume Control. */ wake_lock_timeout(&keypad_data->wlock, 1 * HZ); *new_state = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE31_0); *(new_state + 1) = __raw_readl(keypad_data->base + OMAP4_KBD_FULLCODE63_32); // LGE_CHANGE_S [[email protected]] 2012-06-06 , add to check H/W status if(debug_mask) { printk("========================================================\n"); printk("%s: [%#x][%#x]\n", __func__, *new_state, *(new_state+1)); printk("========================================================\n"); } // LGE_CHANGE_E [[email protected]] 2012-06-06 for (col = 0; col < keypad_data->cols; col++) { changed = key_state[col] ^ keypad_data->key_state[col]; if (!changed) continue; for (row = 0; row < keypad_data->rows; row++) { if (changed & (1 << row)) { code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift); // LGE_CHANGE_S [[email protected]] 2012-06-06 , add to check H/W status if(debug_mask) { printk("%s: [changed][col][row][code] = [%#x][%d][%d][%d]\n", __func__, changed, col, row, code); printk("========================================================\n"); } // LGE_CHANGE_E [[email protected]] 2012-06-06 //[email protected] => [START] keylock command #ifdef CONFIG_MACH_LGE_COSMO if( keypad_data->keymap[code] && !atcmd_keylock) { #else if( keypad_data->keymap[code] ) { #endif //[email protected] <= [END] input_event(input_dev, EV_MSC, MSC_SCAN, code); input_report_key(input_dev, keypad_data->keymap[code], (bool)(key_state[col] & (1 << row))); #ifdef CONFIG_MACH_LGE_U2 /* [email protected] - 2012/05/21 - the HOME_key is added */ printk("[omap4-keypad] %s KEY %s\n", (keypad_data->keymap[code] == KEY_VOLUMEUP) ? "Vol_UP" : ((keypad_data->keymap[code] == KEY_VOLUMEDOWN) ? "Vol_DOWN" : "HOME"), (key_state[col] & (1 << row)) ? "PRESS" : "RELEASE" ); #else printk("[omap4-keypad] %s KEY %s\n", (keypad_data->keymap[code] == KEY_VOLUMEUP) ? "Vol_UP" : ((keypad_data->keymap[code] == KEY_VOLUMEDOWN) ? "Vol_DOWN" : "CAPTURE"), (key_state[col] & (1 << row)) ? "PRESS" : "RELEASE" ); #endif #ifdef CONFIG_INPUT_LGE_GKPD gkpd_report_key(keypad_data->keymap[code], (bool)(key_state[col] & (1 << row))); #endif break; } /* LGE_SJIT 2012-01-05 [[email protected]] * for Android SafeMode * [[email protected]] 2011-06-10, * [P940] for enable the saving-mode */ #ifdef CONFIG_KEYBOARD_OMAP4_SAFEMODE if (keypad_data->keymap[code] == KEY_VOLUMEUP) { safemode_key = !!(key_state[col] & (1 << row)); } #endif } } } input_sync(input_dev); memcpy(keypad_data->key_state, key_state, sizeof(keypad_data->key_state)); /* clear pending interrupts */ __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), keypad_data->base + OMAP4_KBD_IRQSTATUS); printk("#################################### %s is finished!!!!!\n", __func__); return IRQ_HANDLED; } static int omap4_keypad_open(struct input_dev *input) { struct omap4_keypad *keypad_data = input_get_drvdata(input); #ifdef KBD_DEBUG printk("omap4-keypad: omap4_keypad_open \n"); #endif pm_runtime_get_sync(input->dev.parent); disable_irq(keypad_data->irq); __raw_writel(OMAP4_DEF_CTRL_NOSOFTMODE | (OMAP4_VAL_PVT << OMAP4_DEF_CTRL_PTV), keypad_data->base + OMAP4_KBD_CTRL); __raw_writel(OMAP4_VAL_DEBOUNCINGTIME, keypad_data->base + OMAP4_KBD_DEBOUNCINGTIME); /* Enable event IRQ*/ __raw_writel(OMAP4_DEF_IRQENABLE_EVENTEN, keypad_data->base + OMAP4_KBD_IRQENABLE); /* Enable event wkup*/ __raw_writel(OMAP4_DEF_WUP_EVENT_ENA, keypad_data->base + OMAP4_KBD_WAKEUPENABLE); /* clear pending interrupts */ __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), keypad_data->base + OMAP4_KBD_IRQSTATUS); enable_irq(keypad_data->irq); return 0; } static void omap4_keypad_close(struct input_dev *input) { struct omap4_keypad *keypad_data = input_get_drvdata(input); disable_irq(keypad_data->irq); /* Disable interrupts */ __raw_writel(OMAP4_VAL_IRQDISABLE, keypad_data->base + OMAP4_KBD_IRQENABLE); /* clear pending interrupts */ __raw_writel(__raw_readl(keypad_data->base + OMAP4_KBD_IRQSTATUS), keypad_data->base + OMAP4_KBD_IRQSTATUS); enable_irq(keypad_data->irq); #ifdef KBD_DEBUG printk("omap4-keypad: omap4_keypad_close \n"); #endif pm_runtime_put_sync(input->dev.parent); } static int __devinit omap4_keypad_probe(struct platform_device *pdev) { const struct omap4_keypad_platform_data *pdata; struct omap4_keypad *keypad_data; struct input_dev *input_dev; struct resource *res; resource_size_t size; unsigned int row_shift, max_keys; int irq; int error; /* platform data */ pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no base address specified\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "no keyboard irq assigned\n"); return -EINVAL; } if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } row_shift = get_count_order(pdata->cols); max_keys = pdata->rows << row_shift; keypad_data = kzalloc(sizeof(struct omap4_keypad) + max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL); if (!keypad_data) { dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); return -ENOMEM; } size = resource_size(res); res = request_mem_region(res->start, size, pdev->name); if (!res) { dev_err(&pdev->dev, "can't request mem region\n"); error = -EBUSY; goto err_free_keypad; } keypad_data->base = ioremap(res->start, resource_size(res)); if (!keypad_data->base) { dev_err(&pdev->dev, "can't ioremap mem resource\n"); error = -ENOMEM; goto err_release_mem; } keypad_data->irq = irq; keypad_data->row_shift = row_shift; keypad_data->rows = pdata->rows; keypad_data->cols = pdata->cols; keypad_data->keypad_pad_wkup = pdata->keypad_pad_wkup; /* input device allocation */ keypad_data->input = input_dev = input_allocate_device(); if (!input_dev) { error = -ENOMEM; goto err_unmap; } input_dev->name = pdev->name; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0001; input_dev->open = omap4_keypad_open; input_dev->close = omap4_keypad_close; input_dev->keycode = keypad_data->keymap; input_dev->keycodesize = sizeof(keypad_data->keymap[0]); input_dev->keycodemax = max_keys; __set_bit(EV_KEY, input_dev->evbit); __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad_data); matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input_dev->keycode, input_dev->keybit); /* LGE_SJIT 2011-12-06 [[email protected]] MHL keybits * jk.koo kibu.lee 20110810 MHL RCP codes into media keys and * transfer these to the input manager */ #if defined(CONFIG_MHL_INPUT_RCP) hdmi_common_register_keys(input_dev); #endif /* LGE_SJIT 2011-12-09 [[email protected]] for hook key */ #if defined(CONFIG_SND_OMAP_SOC_LGE_JACK) __set_bit(KEY_HOOK, input_dev->keybit); #endif /* LGE_SJIT 2011-01-05 [[email protected]] Add wake lock */ wake_lock_init(&keypad_data->wlock, WAKE_LOCK_SUSPEND, "omap4-keypad"); /* * Set irq level detection for mpu. Edge event are missed * in gic if the mpu is in low power and keypad event * is a wakeup. */ error = request_irq(keypad_data->irq, omap4_keypad_interrupt, IRQF_TRIGGER_HIGH, "omap4-keypad", keypad_data); if (error) { dev_err(&pdev->dev, "failed to register interrupt\n"); goto err_free_input; } enable_irq_wake(OMAP44XX_IRQ_KBD_CTL); pm_runtime_enable(&pdev->dev); error = input_register_device(keypad_data->input); if (error < 0) { dev_err(&pdev->dev, "failed to register input device\n"); goto err_pm_disable; } platform_set_drvdata(pdev, keypad_data); /* LGE_SJIT 2012-01-05 [[email protected]] for Android SafeMode * [[email protected]] 2011-06-10, [P940] for enable the saving-mode */ #ifdef CONFIG_KEYBOARD_OMAP4_SAFEMODE error = device_create_file(&pdev->dev, &dev_attr_key_saving); if (error < 0) { dev_warn(&pdev->dev, "failed to create sysfs for key_saving\n"); } #endif // LGE_CHANGE_S [[email protected]] 2012-06-06 , add debug_mask to check the H/W status for keypad immediately error = device_create_file(&pdev->dev, &dev_attr_keypad_debug); if (error < 0) { dev_warn(&pdev->dev, "failed to create sysfs for keypad_debug\n"); } // LGE_CHANGE_E [[email protected]] 2012-06-06 //[email protected] => [START] keylock command #ifdef CONFIG_MACH_LGE_COSMO error = device_create_file(&pdev->dev, &dev_attr_keylock); if (error) { printk( "keypad: keylock create file: Fail\n"); device_remove_file(&pdev->dev, &dev_attr_keylock); } #endif //[email protected] <= [END] /* LGE_SJIT 2011-12-06 [[email protected]] export input handle */ #ifdef CONFIG_MACH_LGE lge_input_set(input_dev); #endif return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); free_irq(keypad_data->irq, keypad_data); /* LGE_SJIT 2011-01-05 [[email protected]] Add wake lock */ wake_lock_destroy(&keypad_data->wlock); err_free_input: input_free_device(input_dev); err_unmap: iounmap(keypad_data->base); err_release_mem: release_mem_region(res->start, size); err_free_keypad: kfree(keypad_data); return error; } static int __devexit omap4_keypad_remove(struct platform_device *pdev) { struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); struct resource *res; // LGE_CHANGE_S [[email protected]] 2012-06-06 , add debug_mask to check the H/W status for keypad immediately device_remove_file(&pdev->dev, &dev_attr_keypad_debug); // LGE_CHANGE_E [[email protected]] 2012-06-06 //[email protected] => [START] keylock command #ifdef CONFIG_MACH_LGE_COSMO device_remove_file(&pdev->dev, &dev_attr_keylock); #endif //[email protected] <= [END] /* LGE_SJIT 2012-01-05 [[email protected]] for Android SafeMode * [[email protected]] 2011-06-10, [P940] for enable the saving-mode */ #ifdef CONFIG_KEYBOARD_OMAP4_SAFEMODE device_remove_file(&pdev->dev, &dev_attr_key_saving); #endif free_irq(keypad_data->irq, keypad_data); /* LGE_SJIT 2011-01-05 [[email protected]] Add wake lock */ wake_lock_destroy(&keypad_data->wlock); pm_runtime_disable(&pdev->dev); input_unregister_device(keypad_data->input); iounmap(keypad_data->base); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, resource_size(res)); kfree(keypad_data); platform_set_drvdata(pdev, NULL); return 0; } static int omap4_keypad_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); if (keypad_data->keypad_pad_wkup) keypad_data->keypad_pad_wkup(1); return 0; } static int omap4_keypad_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct omap4_keypad *keypad_data = platform_get_drvdata(pdev); if (keypad_data->keypad_pad_wkup) keypad_data->keypad_pad_wkup(0); return 0; } static const struct dev_pm_ops omap4_keypad_pm_ops = { .suspend = omap4_keypad_suspend, .resume = omap4_keypad_resume, }; static struct platform_driver omap4_keypad_driver = { .probe = omap4_keypad_probe, .remove = __devexit_p(omap4_keypad_remove), .driver = { .name = "omap4-keypad", .owner = THIS_MODULE, .pm = &omap4_keypad_pm_ops, }, }; static int __init omap4_keypad_init(void) { return platform_driver_register(&omap4_keypad_driver); } module_init(omap4_keypad_init); static void __exit omap4_keypad_exit(void) { platform_driver_unregister(&omap4_keypad_driver); }
/* * keypad controller should be initialized in the following sequence * only, otherwise it might get into FSM stuck state. * * - Initialize keypad control parameters, like no. of rows, columns, * timing values etc., * - configure rows and column gpios pull up/down. * - set irq edge type. * - enable the keypad controller. */ static int pmic8xxx_kp_probe(struct platform_device *pdev) { unsigned int rows, cols; bool repeat; bool wakeup; struct pmic8xxx_kp *kp; int rc; unsigned int ctrl_val; rc = matrix_keypad_parse_of_params(&pdev->dev, &rows, &cols); if (rc) return rc; if (cols > PM8XXX_MAX_COLS || rows > PM8XXX_MAX_ROWS || cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } repeat = !of_property_read_bool(pdev->dev.of_node, "linux,input-no-autorepeat"); wakeup = of_property_read_bool(pdev->dev.of_node, "linux,keypad-wakeup"); kp = devm_kzalloc(&pdev->dev, sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; kp->regmap = dev_get_regmap(pdev->dev.parent, NULL); if (!kp->regmap) return -ENODEV; platform_set_drvdata(pdev, kp); kp->num_rows = rows; kp->num_cols = cols; kp->dev = &pdev->dev; kp->input = devm_input_allocate_device(&pdev->dev); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); return -ENOMEM; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); return kp->key_sense_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); return kp->key_stuck_irq; } kp->input->name = "PMIC8XXX keypad"; kp->input->phys = "pmic8xxx_keypad/input0"; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; rc = matrix_keypad_build_keymap(NULL, NULL, PM8XXX_MAX_ROWS, PM8XXX_MAX_COLS, kp->keycodes, kp->input); if (rc) { dev_err(&pdev->dev, "failed to build keymap\n"); return rc; } if (repeat) __set_bit(EV_REP, kp->input->evbit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp, pdev); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); return rc; } rc = devm_request_any_context_irq(&pdev->dev, kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); return rc; } rc = devm_request_any_context_irq(&pdev->dev, kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); return rc; } rc = regmap_read(kp->regmap, KEYP_CTRL, &ctrl_val); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); return rc; } kp->ctrl_reg = ctrl_val; rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); return rc; } device_init_wakeup(&pdev->dev, wakeup); return 0; }
static int spear_kbd_probe(struct platform_device *pdev) { struct kbd_platform_data *pdata = dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap = pdata ? pdata->keymap : NULL; struct spear_kbd *kbd; struct input_dev *input_dev; struct resource *res; int irq; int error; irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "not able to get irq for the device\n"); return irq; } kbd = devm_kzalloc(&pdev->dev, sizeof(*kbd), GFP_KERNEL); if (!kbd) { dev_err(&pdev->dev, "not enough memory for driver data\n"); return -ENOMEM; } input_dev = devm_input_allocate_device(&pdev->dev); if (!input_dev) { dev_err(&pdev->dev, "unable to allocate input device\n"); return -ENOMEM; } kbd->input = input_dev; kbd->irq = irq; if (!pdata) { error = spear_kbd_parse_dt(pdev, kbd); if (error) return error; } else { kbd->mode = pdata->mode; kbd->rep = pdata->rep; kbd->suspended_rate = pdata->suspended_rate; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); kbd->io_base = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(kbd->io_base)) return PTR_ERR(kbd->io_base); kbd->clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(kbd->clk)) return PTR_ERR(kbd->clk); input_dev->name = "Spear Keyboard"; input_dev->phys = "keyboard/input0"; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0100; input_dev->open = spear_kbd_open; input_dev->close = spear_kbd_close; error = matrix_keypad_build_keymap(keymap, NULL, NUM_ROWS, NUM_COLS, kbd->keycodes, input_dev); if (error) { dev_err(&pdev->dev, "Failed to build keymap\n"); return error; } if (kbd->rep) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, kbd); error = devm_request_irq(&pdev->dev, irq, spear_kbd_interrupt, 0, "keyboard", kbd); if (error) { dev_err(&pdev->dev, "request_irq failed\n"); return error; } error = clk_prepare(kbd->clk); if (error) return error; error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "Unable to register keyboard device\n"); clk_unprepare(kbd->clk); return error; } device_init_wakeup(&pdev->dev, 1); platform_set_drvdata(pdev, kbd); return 0; }
static int __devinit imx_keypad_probe(struct platform_device *pdev) { const struct matrix_keymap_data *keymap_data = pdev->dev.platform_data; struct imx_keypad *keypad; struct input_dev *input_dev; struct resource *res; int irq, error, i; if (keymap_data == NULL) { dev_err(&pdev->dev, "no keymap defined\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "no irq defined in platform data\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "no I/O memory defined in platform data\n"); return -EINVAL; } res = request_mem_region(res->start, resource_size(res), pdev->name); if (res == NULL) { dev_err(&pdev->dev, "failed to request I/O memory\n"); return -EBUSY; } input_dev = input_allocate_device(); if (!input_dev) { dev_err(&pdev->dev, "failed to allocate the input device\n"); error = -ENOMEM; goto failed_rel_mem; } keypad = kzalloc(sizeof(struct imx_keypad), GFP_KERNEL); if (!keypad) { dev_err(&pdev->dev, "not enough memory for driver data\n"); error = -ENOMEM; goto failed_free_input; } keypad->input_dev = input_dev; keypad->irq = irq; keypad->stable_count = 0; setup_timer(&keypad->check_matrix_timer, imx_keypad_check_for_events, (unsigned long) keypad); keypad->mmio_base = ioremap(res->start, resource_size(res)); if (keypad->mmio_base == NULL) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); error = -ENOMEM; goto failed_free_priv; } keypad->clk = clk_get(&pdev->dev, "kpp"); if (IS_ERR(keypad->clk)) { dev_err(&pdev->dev, "failed to get keypad clock\n"); error = PTR_ERR(keypad->clk); goto failed_unmap; } /* Search for rows and cols enabled */ for (i = 0; i < keymap_data->keymap_size; i++) { keypad->rows_en_mask |= 1 << KEY_ROW(keymap_data->keymap[i]); keypad->cols_en_mask |= 1 << KEY_COL(keymap_data->keymap[i]); } if (keypad->rows_en_mask > ((1 << MAX_MATRIX_KEY_ROWS) - 1) || keypad->cols_en_mask > ((1 << MAX_MATRIX_KEY_COLS) - 1)) { dev_err(&pdev->dev, "invalid key data (too many rows or colums)\n"); error = -EINVAL; goto failed_clock_put; } dev_dbg(&pdev->dev, "enabled rows mask: %x\n", keypad->rows_en_mask); dev_dbg(&pdev->dev, "enabled cols mask: %x\n", keypad->cols_en_mask); /* Init the Input device */ input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->open = imx_keypad_open; input_dev->close = imx_keypad_close; input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_REP); input_dev->keycode = keypad->keycodes; input_dev->keycodesize = sizeof(keypad->keycodes[0]); input_dev->keycodemax = ARRAY_SIZE(keypad->keycodes); matrix_keypad_build_keymap(keymap_data, MATRIX_ROW_SHIFT, keypad->keycodes, input_dev->keybit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); /* Ensure that the keypad will stay dormant until opened */ imx_keypad_inhibit(keypad); error = request_irq(irq, imx_keypad_irq_handler, 0, pdev->name, keypad); if (error) { dev_err(&pdev->dev, "failed to request IRQ\n"); goto failed_clock_put; } /* Register the input device */ error = input_register_device(input_dev); if (error) { dev_err(&pdev->dev, "failed to register input device\n"); goto failed_free_irq; } platform_set_drvdata(pdev, keypad); device_init_wakeup(&pdev->dev, 1); return 0; failed_free_irq: free_irq(irq, pdev); failed_clock_put: clk_put(keypad->clk); failed_unmap: iounmap(keypad->mmio_base); failed_free_priv: kfree(keypad); failed_free_input: input_free_device(input_dev); failed_rel_mem: release_mem_region(res->start, resource_size(res)); return error; }
static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) { const struct pm8xxx_keypad_platform_data *pdata = dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; u8 ctrl_val; struct device *sec_key; struct pm_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; struct pm_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = PM_GPIO_VIN_S4, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || pdata->num_cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0) || pdata->debounce_ms > MAX_DEBOUNCE_TIME || pdata->debounce_ms < MIN_DEBOUNCE_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; platform_set_drvdata(pdev, kp); kp->pdata = pdata; kp->dev = &pdev->dev; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = kp->keycodes; kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(kp->keycodes); kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, kp->input->keycode, kp->input->keybit); get_volumekey_matrix(keymap_data, &volup_matrix, &voldown_matrix); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_get_irq; } rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, pdata->num_cols, kp, &kypd_sns); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, pdata->num_rows, kp, &kypd_drv); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_get_irq; } rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); goto err_pmic_reg_read; } rc = request_threaded_irq(MSM_GPIO_KEY_VOLUP_IRQ , NULL, pmic8058_volume_up_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "vol_up", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request vol_up irq\n"); goto err_req_sense_irq; } rc = request_threaded_irq(MSM_GPIO_KEY_VOLDOWN_IRQ , NULL, pmic8058_volume_down_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "vol_down", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request vol_down irq\n"); goto err_req_sense_irq; } kp->ctrl_reg = ctrl_val; #if defined CONFIG_MACH_VITAL2REFRESH gpio_tlmm_config(GPIO_CFG(MSM_HALL_IC, 1, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE); input_set_capability(kp->input, EV_SW, SW_LID); if (gpio_get_value(MSM_HALL_IC)) { input_report_switch(kp->input, SW_LID, 1); } else { input_report_switch(kp->input, SW_LID, 0); } input_sync(kp->input); printk(KERN_INFO "[input_report_switch] slide_int - !gpio_hall_ic %s\n", gpio_get_value(MSM_HALL_IC) == 0 ? "OPEN" : "CLOSE"); rc = request_threaded_irq(MSM_GPIO_TO_INT(MSM_HALL_IC), NULL, hall_ic_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "hall_ic", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request hall_ic irq\n"); goto err_hall_ic_irq; } #endif rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_pmic_reg_read; } sec_key = device_create(sec_class, NULL, 0, NULL, "sec_key"); if (IS_ERR(sec_key)) pr_err("Failed to create device(sec_key)!\n"); rc = device_create_file(sec_key, &dev_attr_sec_key_pressed); if (rc) { pr_err("Failed to create device file - pressed(%s), err(%d)!\n", dev_attr_sec_key_pressed.attr.name, rc); } dev_set_drvdata(sec_key, kp); device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_pmic_reg_read: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); #if defined CONFIG_MACH_VITAL2REFRESH err_hall_ic_irq: #endif err_req_sense_irq: err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: platform_set_drvdata(pdev, NULL); kfree(kp); return rc; } static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) { struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, kp); free_irq(kp->key_sense_irq, kp); input_unregister_device(kp->input); kfree(kp); platform_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM_SLEEP static int pmic8xxx_kp_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); #if defined CONFIG_MACH_VITAL2REFRESH enable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to wakeup in case of sleep */ #endif if (input_dev->users) pmic8xxx_kp_disable(kp); mutex_unlock(&input_dev->mutex); } return 0; } static int pmic8xxx_kp_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { disable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); #if defined CONFIG_MACH_VITAL2REFRESH disable_irq_wake(MSM_GPIO_TO_INT(MSM_HALL_IC)); /* to match irq pair */ #endif if (input_dev->users) pmic8xxx_kp_enable(kp); mutex_unlock(&input_dev->mutex); } return 0; } #endif static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .remove = __devexit_p(pmic8xxx_kp_remove), .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, }, }; static int __init pmic8xxx_kp_init(void) { return platform_driver_register(&pmic8xxx_kp_driver); } module_init(pmic8xxx_kp_init); static void __exit pmic8xxx_kp_exit(void) { platform_driver_unregister(&pmic8xxx_kp_driver); } module_exit(pmic8xxx_kp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad"); MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
static int cros_ec_keyb_get_state(struct cros_ec_keyb *ckdev, uint8_t *kb_state) { struct cros_ec_command msg = { .version = 0, .command = EC_CMD_MKBP_STATE, .outdata = NULL, .outsize = 0, .indata = kb_state, .insize = ckdev->cols, }; return ckdev->ec->cmd_xfer(ckdev->ec, &msg); } static irqreturn_t cros_ec_keyb_irq(int irq, void *data) { struct cros_ec_keyb *ckdev = data; struct cros_ec_device *ec = ckdev->ec; int ret; uint8_t kb_state[ckdev->cols]; if (device_may_wakeup(ec->dev)) pm_wakeup_event(ec->dev, 0); ret = cros_ec_keyb_get_state(ckdev, kb_state); if (ret >= 0) cros_ec_keyb_process(ckdev, kb_state, ret); else dev_err(ec->dev, "failed to get keyboard state: %d\n", ret); return IRQ_HANDLED; } static int cros_ec_keyb_open(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); struct cros_ec_device *ec = ckdev->ec; return request_threaded_irq(ec->irq, NULL, cros_ec_keyb_irq, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "cros_ec_keyb", ckdev); } static void cros_ec_keyb_close(struct input_dev *dev) { struct cros_ec_keyb *ckdev = input_get_drvdata(dev); struct cros_ec_device *ec = ckdev->ec; free_irq(ec->irq, ckdev); } static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct device *dev = ec->dev; struct cros_ec_keyb *ckdev; struct input_dev *idev; struct device_node *np; int err; np = pdev->dev.of_node; if (!np) return -ENODEV; ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, &ckdev->cols); if (err) return err; ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->old_kb_state) return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; if (!ec->irq) { dev_err(dev, "no EC IRQ specified\n"); return -EINVAL; } ckdev->ec = ec; ckdev->dev = dev; dev_set_drvdata(&pdev->dev, ckdev); idev->name = ec->ec_name; idev->phys = ec->phys_name; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = &pdev->dev; idev->open = cros_ec_keyb_open; idev->close = cros_ec_keyb_close; ckdev->ghost_filter = of_property_read_bool(np, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, NULL, idev); if (err) { dev_err(dev, "cannot build key matrix\n"); return err; } ckdev->row_shift = get_count_order(ckdev->cols); input_set_capability(idev, EV_MSC, MSC_SCAN); input_set_drvdata(idev, ckdev); ckdev->idev = idev; err = input_register_device(ckdev->idev); if (err) { dev_err(dev, "cannot register input device\n"); return err; } return 0; } #ifdef CONFIG_PM_SLEEP /* Clear any keys in the buffer */ static void cros_ec_keyb_clear_keyboard(struct cros_ec_keyb *ckdev) { uint8_t old_state[ckdev->cols]; uint8_t new_state[ckdev->cols]; unsigned long duration; int i, ret; /* * Keep reading until we see that the scan state does not change. * That indicates that we are done. * * Assume that the EC keyscan buffer is at most 32 deep. */ duration = jiffies; ret = cros_ec_keyb_get_state(ckdev, new_state); for (i = 1; !ret && i < 32; i++) { memcpy(old_state, new_state, sizeof(old_state)); ret = cros_ec_keyb_get_state(ckdev, new_state); if (0 == memcmp(old_state, new_state, sizeof(old_state))) break; } duration = jiffies - duration; dev_info(ckdev->dev, "Discarded %d keyscan(s) in %dus\n", i, jiffies_to_usecs(duration)); }
static int matrix_keypad_probe(struct platform_device *pdev) { const struct matrix_keypad_platform_data *pdata; struct matrix_keypad *keypad; struct input_dev *input_dev; int err; pdata = dev_get_platdata(&pdev->dev); if (!pdata) { pdata = matrix_keypad_parse_dt(&pdev->dev); if (IS_ERR(pdata)) { dev_err(&pdev->dev, "no platform data defined\n"); return PTR_ERR(pdata); } } else if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL); input_dev = input_allocate_device(); if (!keypad || !input_dev) { err = -ENOMEM; goto err_free_mem; } keypad->input_dev = input_dev; keypad->pdata = pdata; keypad->row_shift = get_count_order(pdata->num_col_gpios); keypad->stopped = true; INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan); spin_lock_init(&keypad->lock); input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->dev.parent = &pdev->dev; input_dev->open = matrix_keypad_start; input_dev->close = matrix_keypad_stop; err = matrix_keypad_build_keymap(pdata->keymap_data, NULL, pdata->num_row_gpios, pdata->num_col_gpios, NULL, input_dev); if (err) { dev_err(&pdev->dev, "failed to build keymap\n"); goto err_free_mem; } if (!pdata->no_autorepeat) __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad); err = matrix_keypad_init_gpio(pdev, keypad); if (err) goto err_free_mem; err = input_register_device(keypad->input_dev); if (err) goto err_free_gpio; device_init_wakeup(&pdev->dev, pdata->wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_gpio: matrix_keypad_free_gpio(keypad); err_free_mem: input_free_device(input_dev); kfree(keypad); return err; }
static int tc3589x_keypad_probe(struct platform_device *pdev) { struct tc3589x *tc3589x = dev_get_drvdata(pdev->dev.parent); struct tc_keypad *keypad; struct input_dev *input; const struct tc3589x_keypad_platform_data *plat; int error, irq; plat = tc3589x_keypad_of_probe(&pdev->dev); if (IS_ERR(plat)) { dev_err(&pdev->dev, "invalid keypad platform data\n"); return PTR_ERR(plat); } irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; keypad = kzalloc(sizeof(struct tc_keypad), GFP_KERNEL); input = input_allocate_device(); if (!keypad || !input) { dev_err(&pdev->dev, "failed to allocate keypad memory\n"); error = -ENOMEM; goto err_free_mem; } keypad->board = plat; keypad->input = input; keypad->tc3589x = tc3589x; input->id.bustype = BUS_I2C; input->name = pdev->name; input->dev.parent = &pdev->dev; input->open = tc3589x_keypad_open; input->close = tc3589x_keypad_close; error = matrix_keypad_build_keymap(plat->keymap_data, NULL, TC3589x_MAX_KPROW, TC3589x_MAX_KPCOL, NULL, input); if (error) { dev_err(&pdev->dev, "Failed to build keymap\n"); goto err_free_mem; } keypad->keymap = input->keycode; input_set_capability(input, EV_MSC, MSC_SCAN); if (!plat->no_autorepeat) __set_bit(EV_REP, input->evbit); input_set_drvdata(input, keypad); error = request_threaded_irq(irq, NULL, tc3589x_keypad_irq, plat->irqtype | IRQF_ONESHOT, "tc3589x-keypad", keypad); if (error < 0) { dev_err(&pdev->dev, "Could not allocate irq %d,error %d\n", irq, error); goto err_free_mem; } error = input_register_device(input); if (error) { dev_err(&pdev->dev, "Could not register input device\n"); goto err_free_irq; } /* let platform decide if keypad is a wakeup source or not */ device_init_wakeup(&pdev->dev, plat->enable_wakeup); device_set_wakeup_capable(&pdev->dev, plat->enable_wakeup); platform_set_drvdata(pdev, keypad); return 0; err_free_irq: free_irq(irq, keypad); err_free_mem: input_free_device(input); kfree(keypad); return error; }
static int cros_ec_keyb_probe(struct platform_device *pdev) { struct cros_ec_device *ec = dev_get_drvdata(pdev->dev.parent); struct device *dev = ec->dev; struct cros_ec_keyb *ckdev; struct input_dev *idev; struct device_node *np; int err; np = pdev->dev.of_node; if (!np) return -ENODEV; ckdev = devm_kzalloc(&pdev->dev, sizeof(*ckdev), GFP_KERNEL); if (!ckdev) return -ENOMEM; err = matrix_keypad_parse_of_params(&pdev->dev, &ckdev->rows, &ckdev->cols); if (err) return err; ckdev->valid_keys = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->valid_keys) return -ENOMEM; ckdev->old_kb_state = devm_kzalloc(&pdev->dev, ckdev->cols, GFP_KERNEL); if (!ckdev->old_kb_state) return -ENOMEM; idev = devm_input_allocate_device(&pdev->dev); if (!idev) return -ENOMEM; if (!ec->irq) { dev_err(dev, "no EC IRQ specified\n"); return -EINVAL; } ckdev->ec = ec; ckdev->dev = dev; dev_set_drvdata(&pdev->dev, ckdev); idev->name = CROS_EC_DEV_NAME; idev->phys = ec->phys_name; __set_bit(EV_REP, idev->evbit); idev->id.bustype = BUS_VIRTUAL; idev->id.version = 1; idev->id.product = 0; idev->dev.parent = &pdev->dev; idev->open = cros_ec_keyb_open; idev->close = cros_ec_keyb_close; ckdev->ghost_filter = of_property_read_bool(np, "google,needs-ghost-filter"); err = matrix_keypad_build_keymap(NULL, NULL, ckdev->rows, ckdev->cols, NULL, idev); if (err) { dev_err(dev, "cannot build key matrix\n"); return err; } ckdev->row_shift = get_count_order(ckdev->cols); input_set_capability(idev, EV_MSC, MSC_SCAN); input_set_drvdata(idev, ckdev); ckdev->idev = idev; cros_ec_keyb_compute_valid_keys(ckdev); err = input_register_device(ckdev->idev); if (err) { dev_err(dev, "cannot register input device\n"); return err; } return 0; }
/** * db5500_keypad_probe() - Initialze the the keypad driver * @pdev: pointer to platform device structure * * This function will allocate and initialize the instance * data and request the irq and register to input subsystem driver. */ static int __devinit db5500_keypad_probe(struct platform_device *pdev) { struct db5500_keypad_platform_data *plat; struct db5500_keypad *keypad; struct resource *res; struct input_dev *input; void __iomem *base; struct clk *clk; int ret; int irq; int i; plat = pdev->dev.platform_data; if (!plat) { dev_err(&pdev->dev, "invalid keypad platform data\n"); ret = -EINVAL; goto out_ret; } irq = platform_get_irq(pdev, 0); if (irq < 0) { dev_err(&pdev->dev, "failed to get keypad irq\n"); ret = -EINVAL; goto out_ret; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "missing platform resources\n"); ret = -EINVAL; goto out_ret; } res = request_mem_region(res->start, resource_size(res), pdev->name); if (!res) { dev_err(&pdev->dev, "failed to request I/O memory\n"); ret = -EBUSY; goto out_ret; } base = ioremap(res->start, resource_size(res)); if (!base) { dev_err(&pdev->dev, "failed to remap I/O memory\n"); ret = -ENXIO; goto out_freerequest_memregions; } clk = clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { dev_err(&pdev->dev, "failed to clk_get\n"); ret = PTR_ERR(clk); goto out_iounmap; } keypad = kzalloc(sizeof(struct db5500_keypad), GFP_KERNEL); if (!keypad) { dev_err(&pdev->dev, "failed to allocate keypad memory\n"); ret = -ENOMEM; goto out_freeclk; } input = input_allocate_device(); if (!input) { dev_err(&pdev->dev, "failed to input_allocate_device\n"); ret = -ENOMEM; goto out_freekeypad; } keypad->regulator = regulator_get(&pdev->dev, "v-ape"); if (IS_ERR(keypad->regulator)) { dev_err(&pdev->dev, "regulator_get failed\n"); keypad->regulator = NULL; ret = -EINVAL; goto out_regulator_get; } else { ret = regulator_enable(keypad->regulator); if (ret < 0) { dev_err(&pdev->dev, "regulator_enable failed\n"); goto out_regulator_enable; } } input->id.bustype = BUS_HOST; input->name = "db5500-keypad"; input->dev.parent = &pdev->dev; input->keycode = keypad->keymap; input->keycodesize = sizeof(keypad->keymap[0]); input->keycodemax = ARRAY_SIZE(keypad->keymap); input_set_capability(input, EV_MSC, MSC_SCAN); __set_bit(EV_KEY, input->evbit); if (!plat->no_autorepeat) __set_bit(EV_REP, input->evbit); matrix_keypad_build_keymap(plat->keymap_data, KEYPAD_ROW_SHIFT, input->keycode, input->keybit); ret = input_register_device(input); if (ret) { dev_err(&pdev->dev, "unable to register input device: %d\n", ret); goto out_freeinput; } keypad->irq = irq; keypad->board = plat; keypad->input = input; keypad->base = base; keypad->clk = clk; INIT_DELAYED_WORK(&keypad->switch_work, db5500_gpio_switch_work); INIT_DELAYED_WORK(&keypad->gpio_work, db5500_gpio_release_work); clk_enable(keypad->clk); if (!keypad->board->init) { dev_err(&pdev->dev, "init funtion not defined\n"); ret = -EINVAL; goto out_unregisterinput; } if (keypad->board->init() < 0) { dev_err(&pdev->dev, "keyboard init config failed\n"); ret = -EINVAL; goto out_unregisterinput; } if (!keypad->board->exit) { dev_err(&pdev->dev, "exit funtion not defined\n"); ret = -EINVAL; goto out_unregisterinput; } if (keypad->board->exit() < 0) { dev_err(&pdev->dev, "keyboard exit config failed\n"); ret = -EINVAL; goto out_unregisterinput; } for (i = 0; i < keypad->board->krow; i++) { keypad->db5500_rows[i] = *plat->gpio_input_pins; keypad->gpio_input_irq[i] = GPIO_TO_IRQ(keypad->db5500_rows[i]); plat->gpio_input_pins++; } for (i = 0; i < keypad->board->kcol; i++) { keypad->db5500_cols[i] = *plat->gpio_output_pins; plat->gpio_output_pins++; } for (i = 0; i < keypad->board->krow; i++) { ret = request_threaded_irq(keypad->gpio_input_irq[i], NULL, db5500_keypad_gpio_irq, IRQF_TRIGGER_FALLING | IRQF_NO_SUSPEND, "db5500-keypad-gpio", keypad); if (ret) { dev_err(&pdev->dev, "allocate gpio irq %d failed\n", keypad->gpio_input_irq[i]); goto out_unregisterinput; } enable_irq_wake(keypad->gpio_input_irq[i]); } ret = request_threaded_irq(keypad->irq, NULL, db5500_keypad_irq, IRQF_ONESHOT, "db5500-keypad", keypad); if (ret) { dev_err(&pdev->dev, "allocate irq %d failed\n", keypad->irq); goto out_unregisterinput; } platform_set_drvdata(pdev, keypad); clk_disable(keypad->clk); regulator_disable(keypad->regulator); return 0; out_unregisterinput: input_unregister_device(input); input = NULL; clk_disable(keypad->clk); out_freeinput: input_free_device(input); out_regulator_enable: regulator_put(keypad->regulator); out_regulator_get: input_free_device(input); out_freekeypad: kfree(keypad); out_freeclk: clk_put(clk); out_iounmap: iounmap(base); out_freerequest_memregions: release_mem_region(res->start, resource_size(res)); out_ret: return ret; }
/* * keypad controller should be initialized in the following sequence * only, otherwise it might get into FSM stuck state. * * - Initialize keypad control parameters, like no. of rows, columns, * timing values etc., * - configure rows and column gpios pull up/down. * - set irq edge type. * - enable the keypad controller. */ static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev) { const struct pm8xxx_keypad_platform_data *pdata = dev_get_platdata(&pdev->dev); const struct matrix_keymap_data *keymap_data; struct pmic8xxx_kp *kp; int rc; u8 ctrl_val; struct pm_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = PM_GPIO_VIN_S3, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; struct pm_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = PM_GPIO_VIN_S3, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8XXX_MAX_COLS || pdata->num_rows > PM8XXX_MAX_ROWS || pdata->num_cols < PM8XXX_MIN_COLS) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (!pdata->debounce_ms || ((pdata->debounce_ms % 5) != 0) || pdata->debounce_ms > MAX_DEBOUNCE_TIME || pdata->debounce_ms < MIN_DEBOUNCE_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; platform_set_drvdata(pdev, kp); kp->pdata = pdata; kp->dev = &pdev->dev; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } kp->input->name = pdata->input_name ? : "PMIC8XXX keypad"; kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_I2C; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = kp->keycodes; kp->input->keycodemax = PM8XXX_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(kp->keycodes); kp->input->open = pmic8xxx_kp_open; kp->input->close = pmic8xxx_kp_close; matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT, kp->input->keycode, kp->input->keybit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8xxx_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_get_irq; } rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start, pdata->num_cols, kp, &kypd_sns); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start, pdata->num_rows, kp, &kypd_drv); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_get_irq; } rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); if (rc < 0) { dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n"); goto err_pmic_reg_read; } kp->ctrl_reg = ctrl_val; rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_pmic_reg_read; } device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_pmic_reg_read: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); err_gpio_config: err_get_irq: input_free_device(kp->input); err_alloc_device: platform_set_drvdata(pdev, NULL); kfree(kp); return rc; } static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev) { struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, kp); free_irq(kp->key_sense_irq, kp); input_unregister_device(kp->input); kfree(kp); platform_set_drvdata(pdev, NULL); return 0; } #ifdef CONFIG_PM_SLEEP static int pmic8xxx_kp_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); if (input_dev->users) pmic8xxx_kp_disable(kp); mutex_unlock(&input_dev->mutex); } return 0; } static int pmic8xxx_kp_resume(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct pmic8xxx_kp *kp = platform_get_drvdata(pdev); struct input_dev *input_dev = kp->input; if (device_may_wakeup(dev)) { disable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&input_dev->mutex); if (input_dev->users) pmic8xxx_kp_enable(kp); mutex_unlock(&input_dev->mutex); } return 0; } #endif static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops, pmic8xxx_kp_suspend, pmic8xxx_kp_resume); static struct platform_driver pmic8xxx_kp_driver = { .probe = pmic8xxx_kp_probe, .remove = __devexit_p(pmic8xxx_kp_remove), .driver = { .name = PM8XXX_KEYPAD_DEV_NAME, .owner = THIS_MODULE, .pm = &pm8xxx_kp_pm_ops, }, }; static int __init pmic8xxx_kp_init(void) { return platform_driver_register(&pmic8xxx_kp_driver); } module_init(pmic8xxx_kp_init); static void __exit pmic8xxx_kp_exit(void) { platform_driver_unregister(&pmic8xxx_kp_driver); } module_exit(pmic8xxx_kp_exit); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad"); MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
static int pm8058_kp_config_drv(int gpio_start, int num_gpios) { int rc; struct pm8058_gpio kypd_drv = { .direction = PM_GPIO_DIR_OUT, .output_buffer = PM_GPIO_OUT_BUF_OPEN_DRAIN, .output_value = 0, .pull = PM_GPIO_PULL_NO, .vin_sel = 2, .out_strength = PM_GPIO_STRENGTH_LOW, .function = PM_GPIO_FUNC_1, .inv_int_pol = 1, }; if (gpio_start < 0 || num_gpios < 0 || num_gpios > PM8058_GPIOS) return -EINVAL; while (num_gpios--) { rc = pm8058_gpio_config(gpio_start++, &kypd_drv); if (rc) { pr_err("%s: FAIL pm8058_gpio_config(): rc=%d.\n", __func__, rc); return rc; } } return 0; } static int pm8058_kp_config_sns(int gpio_start, int num_gpios) { int rc; struct pm8058_gpio kypd_sns = { .direction = PM_GPIO_DIR_IN, .pull = PM_GPIO_PULL_UP_31P5, .vin_sel = 2, .out_strength = PM_GPIO_STRENGTH_NO, .function = PM_GPIO_FUNC_NORMAL, .inv_int_pol = 1, }; if (gpio_start < 0 || num_gpios < 0 || num_gpios > PM8058_GPIOS) return -EINVAL; while (num_gpios--) { rc = pm8058_gpio_config(gpio_start++, &kypd_sns); if (rc) { pr_err("%s: FAIL pm8058_gpio_config(): rc=%d.\n", __func__, rc); return rc; } } return 0; } /* * keypad controller should be initialized in the following sequence * only, otherwise it might get into FSM stuck state. * * - Initialize keypad control parameters, like no. of rows, columns, * timing values etc., * - configure rows and column gpios pull up/down. * - set irq edge type. * - enable the keypad controller. */ static int __devinit pmic8058_kp_probe(struct platform_device *pdev) { struct pmic8058_keypad_data *pdata = pdev->dev.platform_data; const struct matrix_keymap_data *keymap_data; struct pmic8058_kp *kp; int rc; unsigned short *keycodes; u8 ctrl_val; struct pm8058_chip *pm_chip; pm_chip = platform_get_drvdata(pdev); if (pm_chip == NULL) { dev_err(&pdev->dev, "no parent data passed in\n"); return -EFAULT; } if (!pdata || !pdata->num_cols || !pdata->num_rows || pdata->num_cols > PM8058_MAX_COLS || pdata->num_rows > PM8058_MAX_ROWS || pdata->num_cols < PM8058_MIN_COLS #if 0 || pdata->num_rows < PM8058_MIN_ROWS #endif ) { dev_err(&pdev->dev, "invalid platform data\n"); return -EINVAL; } if (pdata->rows_gpio_start < 0 || pdata->cols_gpio_start < 0) { dev_err(&pdev->dev, "invalid gpio_start platform data\n"); return -EINVAL; } if (!pdata->scan_delay_ms || pdata->scan_delay_ms > MAX_SCAN_DELAY || pdata->scan_delay_ms < MIN_SCAN_DELAY || !is_power_of_2(pdata->scan_delay_ms)) { dev_err(&pdev->dev, "invalid keypad scan time supplied\n"); return -EINVAL; } if (!pdata->row_hold_ns || pdata->row_hold_ns > MAX_ROW_HOLD_DELAY || pdata->row_hold_ns < MIN_ROW_HOLD_DELAY || ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) { dev_err(&pdev->dev, "invalid keypad row hold time supplied\n"); return -EINVAL; } if (pm8058_rev(pm_chip) == PM_8058_REV_1p0) { if (!pdata->debounce_ms || !is_power_of_2(pdata->debounce_ms[0]) || pdata->debounce_ms[0] > MAX_DEBOUNCE_A0_TIME || pdata->debounce_ms[0] < MIN_DEBOUNCE_A0_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } } else { if (!pdata->debounce_ms || ((pdata->debounce_ms[1] % 5) != 0) || pdata->debounce_ms[1] > MAX_DEBOUNCE_B0_TIME || pdata->debounce_ms[1] < MIN_DEBOUNCE_B0_TIME) { dev_err(&pdev->dev, "invalid debounce time supplied\n"); return -EINVAL; } } keymap_data = pdata->keymap_data; if (!keymap_data) { dev_err(&pdev->dev, "no keymap data supplied\n"); return -EINVAL; } kp = kzalloc(sizeof(*kp), GFP_KERNEL); if (!kp) return -ENOMEM; keycodes = kzalloc(PM8058_MATRIX_MAX_SIZE * sizeof(*keycodes), GFP_KERNEL); if (!keycodes) { rc = -ENOMEM; goto err_alloc_mem; } platform_set_drvdata(pdev, kp); mutex_init(&kp->mutex); kp->pdata = pdata; kp->dev = &pdev->dev; kp->keycodes = keycodes; kp->pm_chip = pm_chip; if (pm8058_rev(pm_chip) == PM_8058_REV_1p0) kp->flags |= KEYF_FIX_LAST_ROW; kp->input = input_allocate_device(); if (!kp->input) { dev_err(&pdev->dev, "unable to allocate input device\n"); rc = -ENOMEM; goto err_alloc_device; } /* Enable runtime PM ops, start in ACTIVE mode */ rc = pm_runtime_set_active(&pdev->dev); if (rc < 0) dev_dbg(&pdev->dev, "unable to set runtime pm state\n"); pm_runtime_enable(&pdev->dev); kp->key_sense_irq = platform_get_irq(pdev, 0); if (kp->key_sense_irq < 0) { dev_err(&pdev->dev, "unable to get keypad sense irq\n"); rc = -ENXIO; goto err_get_irq; } kp->key_stuck_irq = platform_get_irq(pdev, 1); if (kp->key_stuck_irq < 0) { dev_err(&pdev->dev, "unable to get keypad stuck irq\n"); rc = -ENXIO; goto err_get_irq; } if (pdata->input_name) kp->input->name = pdata->input_name; else kp->input->name = "PMIC8058 keypad"; if (pdata->input_phys_device) kp->input->phys = pdata->input_phys_device; else kp->input->phys = "pmic8058_keypad/input0"; kp->input->dev.parent = &pdev->dev; kp->input->id.bustype = BUS_HOST; kp->input->id.version = 0x0001; kp->input->id.product = 0x0001; kp->input->id.vendor = 0x0001; kp->input->evbit[0] = BIT_MASK(EV_KEY); if (pdata->rep) __set_bit(EV_REP, kp->input->evbit); kp->input->keycode = keycodes; kp->input->keycodemax = PM8058_MATRIX_MAX_SIZE; kp->input->keycodesize = sizeof(*keycodes); matrix_keypad_build_keymap(keymap_data, PM8058_ROW_SHIFT, kp->input->keycode, kp->input->keybit); input_set_capability(kp->input, EV_MSC, MSC_SCAN); input_set_drvdata(kp->input, kp); rc = input_register_device(kp->input); if (rc < 0) { dev_err(&pdev->dev, "unable to register keypad input device\n"); goto err_get_irq; } /* initialize keypad state */ memset(kp->keystate, 0xff, sizeof(kp->keystate)); memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate)); rc = pmic8058_kpd_init(kp); if (rc < 0) { dev_err(&pdev->dev, "unable to initialize keypad controller\n"); goto err_kpd_init; } rc = pm8058_kp_config_sns(pdata->cols_gpio_start, pdata->num_cols); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad sense lines\n"); goto err_gpio_config; } rc = pm8058_kp_config_drv(pdata->rows_gpio_start, pdata->num_rows); if (rc < 0) { dev_err(&pdev->dev, "unable to configure keypad drive lines\n"); goto err_gpio_config; } rc = request_threaded_irq(kp->key_sense_irq, NULL, pmic8058_kp_irq, IRQF_TRIGGER_RISING, "pmic-keypad", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad sense irq\n"); goto err_req_sense_irq; } rc = request_threaded_irq(kp->key_stuck_irq, NULL, pmic8058_kp_stuck_irq, IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp); if (rc < 0) { dev_err(&pdev->dev, "failed to request keypad stuck irq\n"); goto err_req_stuck_irq; } rc = pmic8058_kp_read_u8(kp, &ctrl_val, KEYP_CTRL); ctrl_val |= KEYP_CTRL_KEYP_EN; rc = pmic8058_kp_write_u8(kp, ctrl_val, KEYP_CTRL); kp->ctrl_reg = ctrl_val; __dump_kp_regs(kp, "probe"); rc = device_create_file(&pdev->dev, &dev_attr_key_pressed); if (rc < 0) goto err_create_file; rc = device_create_file(&pdev->dev, &dev_attr_disable_kp); if (rc < 0) goto err_create_file; device_init_wakeup(&pdev->dev, pdata->wakeup); return 0; err_create_file: free_irq(kp->key_stuck_irq, kp); err_req_stuck_irq: free_irq(kp->key_sense_irq, kp); err_req_sense_irq: err_gpio_config: err_kpd_init: input_unregister_device(kp->input); kp->input = NULL; err_get_irq: pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); input_free_device(kp->input); err_alloc_device: kfree(keycodes); err_alloc_mem: kfree(kp); return rc; } static int __devexit pmic8058_kp_remove(struct platform_device *pdev) { struct pmic8058_kp *kp = platform_get_drvdata(pdev); // sysfs_remove_group(&pdev->dev.kobj, &pmic8058_keys_attr_group); pm_runtime_set_suspended(&pdev->dev); pm_runtime_disable(&pdev->dev); device_remove_file(&pdev->dev, &dev_attr_key_pressed); device_remove_file(&pdev->dev, &dev_attr_disable_kp); device_init_wakeup(&pdev->dev, 0); free_irq(kp->key_stuck_irq, kp); free_irq(kp->key_sense_irq, kp); input_unregister_device(kp->input); platform_set_drvdata(pdev, NULL); kfree(kp->input->keycode); kfree(kp); return 0; } #ifdef CONFIG_PM static int pmic8058_kp_suspend(struct device *dev) { struct pmic8058_kp *kp = dev_get_drvdata(dev); if (device_may_wakeup(dev) && !pmic8058_kp_disabled(kp)) { enable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&kp->mutex); pmic8058_kp_disable(kp); mutex_unlock(&kp->mutex); } return 0; } static int pmic8058_kp_resume(struct device *dev) { struct pmic8058_kp *kp = dev_get_drvdata(dev); if (device_may_wakeup(dev) && !pmic8058_kp_disabled(kp)) { disable_irq_wake(kp->key_sense_irq); } else { mutex_lock(&kp->mutex); pmic8058_kp_enable(kp); mutex_unlock(&kp->mutex); } return 0; } static struct dev_pm_ops pm8058_kp_pm_ops = { .suspend = pmic8058_kp_suspend, .resume = pmic8058_kp_resume, }; #endif static struct platform_driver pmic8058_kp_driver = { .probe = pmic8058_kp_probe, .remove = __devexit_p(pmic8058_kp_remove), .driver = { .name = "pm8058-keypad", .owner = THIS_MODULE, #ifdef CONFIG_PM .pm = &pm8058_kp_pm_ops, #endif }, }; static int __init pmic8058_kp_init(void) { return platform_driver_register(&pmic8058_kp_driver); } module_init(pmic8058_kp_init); static void __exit pmic8058_kp_exit(void) { platform_driver_unregister(&pmic8058_kp_driver); }
static int __devinit omap4_keypad_probe(struct platform_device *pdev) { const struct omap4_keypad_platform_data *pdata; struct omap4_keypad *keypad_data; struct input_dev *input_dev; struct resource *res; resource_size_t size; unsigned int row_shift, max_keys; int irq; int error; /* platform data */ pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data defined\n"); return -EINVAL; } res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no base address specified\n"); return -EINVAL; } irq = platform_get_irq(pdev, 0); if (!irq) { dev_err(&pdev->dev, "no keyboard irq assigned\n"); return -EINVAL; } if (!pdata->keymap_data) { dev_err(&pdev->dev, "no keymap data defined\n"); return -EINVAL; } row_shift = get_count_order(pdata->cols); max_keys = pdata->rows << row_shift; keypad_data = kzalloc(sizeof(struct omap4_keypad) + max_keys * sizeof(keypad_data->keymap[0]), GFP_KERNEL); if (!keypad_data) { dev_err(&pdev->dev, "keypad_data memory allocation failed\n"); return -ENOMEM; } size = resource_size(res); res = request_mem_region(res->start, size, pdev->name); if (!res) { dev_err(&pdev->dev, "can't request mem region\n"); error = -EBUSY; goto err_free_keypad; } keypad_data->base = ioremap(res->start, resource_size(res)); if (!keypad_data->base) { dev_err(&pdev->dev, "can't ioremap mem resource\n"); error = -ENOMEM; goto err_release_mem; } keypad_data->irq = irq; keypad_data->row_shift = row_shift; keypad_data->rows = pdata->rows; keypad_data->cols = pdata->cols; /* input device allocation */ keypad_data->input = input_dev = input_allocate_device(); if (!input_dev) { error = -ENOMEM; goto err_unmap; } input_dev->name = pdev->name; input_dev->dev.parent = &pdev->dev; input_dev->id.bustype = BUS_HOST; input_dev->id.vendor = 0x0001; input_dev->id.product = 0x0001; input_dev->id.version = 0x0001; input_dev->open = omap4_keypad_open; input_dev->close = omap4_keypad_close; input_dev->keycode = keypad_data->keymap; input_dev->keycodesize = sizeof(keypad_data->keymap[0]); input_dev->keycodemax = max_keys; __set_bit(EV_KEY, input_dev->evbit); __set_bit(EV_REP, input_dev->evbit); input_set_capability(input_dev, EV_MSC, MSC_SCAN); input_set_drvdata(input_dev, keypad_data); matrix_keypad_build_keymap(pdata->keymap_data, row_shift, input_dev->keycode, input_dev->keybit); error = request_irq(keypad_data->irq, omap4_keypad_interrupt, IRQF_TRIGGER_RISING, "omap4-keypad", keypad_data); if (error) { dev_err(&pdev->dev, "failed to register interrupt\n"); goto err_free_input; } pm_runtime_enable(&pdev->dev); error = input_register_device(keypad_data->input); if (error < 0) { dev_err(&pdev->dev, "failed to register input device\n"); goto err_pm_disable; } platform_set_drvdata(pdev, keypad_data); return 0; err_pm_disable: pm_runtime_disable(&pdev->dev); free_irq(keypad_data->irq, keypad_data); err_free_input: input_free_device(input_dev); err_unmap: iounmap(keypad_data->base); err_release_mem: release_mem_region(res->start, size); err_free_keypad: kfree(keypad_data); return error; }