static int axp20x_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); const struct regulator_desc *regulators; struct regulator_config config = { .dev = pdev->dev.parent, .regmap = axp20x->regmap, .driver_data = axp20x, }; int ret, i, nregulators; u32 workmode; switch (axp20x->variant) { case AXP202_ID: case AXP209_ID: regulators = axp20x_regulators; nregulators = AXP20X_REG_ID_MAX; break; case AXP221_ID: regulators = axp22x_regulators; nregulators = AXP22X_REG_ID_MAX; break; default: dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", axp20x->variant); return -EINVAL; } /* This only sets the dcdc freq. Ignore any errors */ axp20x_regulator_parse_dt(pdev); for (i = 0; i < nregulators; i++) { rdev = devm_regulator_register(&pdev->dev, ®ulators[i], &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register %s\n", regulators[i].name); return PTR_ERR(rdev); } ret = of_property_read_u32(rdev->dev.of_node, "x-powers,dcdc-workmode", &workmode); if (!ret) { if (axp20x_set_dcdc_workmode(rdev, i, workmode)) dev_err(&pdev->dev, "Failed to set workmode on %s\n", rdev->desc->name); } } return 0; } static struct platform_driver axp20x_regulator_driver = { .probe = axp20x_regulator_probe, .driver = { .name = "axp20x-regulator", }, }; module_platform_driver(axp20x_regulator_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Carlo Caione <*****@*****.**>"); MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC"); MODULE_ALIAS("platform:axp20x-regulator");
/* * 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_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); 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); #if defined(CONFIG_MACH_KS02) /*sysfs*/ kp->sec_keypad = device_create(sec_class, NULL, 0, kp, "sec_keypad"); if (IS_ERR(kp->sec_keypad)) dev_err(&pdev->dev, "Failed to create sec_key device\n"); rc = sysfs_create_group(&kp->sec_keypad->kobj, &key_attr_group); if (rc) { dev_err(&pdev->dev, "Failed to create the test sysfs: %d\n", rc); } #endif 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); } key_suspend = 1; 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); } key_suspend = 0; 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, }, }; module_platform_driver(pmic8xxx_kp_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("PMIC8XXX keypad driver"); MODULE_VERSION("1.0"); MODULE_ALIAS("platform:pmic8xxx_keypad"); MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
static long rdc321x_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; u32 value; static const struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "RDC321x WDT", }; unsigned long flags; switch (cmd) { case WDIOC_KEEPALIVE: rdc321x_wdt_reset(); break; case WDIOC_GETSTATUS: /* */ spin_lock_irqsave(&rdc321x_wdt_device.lock, flags); pci_read_config_dword(rdc321x_wdt_device.sb_pdev, rdc321x_wdt_device.base_reg, &value); spin_unlock_irqrestore(&rdc321x_wdt_device.lock, flags); if (copy_to_user(argp, &value, sizeof(u32))) return -EFAULT; break; case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_SETOPTIONS: if (copy_from_user(&value, argp, sizeof(int))) return -EFAULT; switch (value) { case WDIOS_ENABLECARD: rdc321x_wdt_start(); break; case WDIOS_DISABLECARD: return rdc321x_wdt_stop(); default: return -EINVAL; } break; default: return -ENOTTY; } return 0; } static ssize_t rdc321x_wdt_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { if (!count) return -EIO; rdc321x_wdt_reset(); return count; } static const struct file_operations rdc321x_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .unlocked_ioctl = rdc321x_wdt_ioctl, .open = rdc321x_wdt_open, .write = rdc321x_wdt_write, .release = rdc321x_wdt_release, }; static struct miscdevice rdc321x_wdt_misc = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &rdc321x_wdt_fops, }; static int __devinit rdc321x_wdt_probe(struct platform_device *pdev) { int err; struct resource *r; struct rdc321x_wdt_pdata *pdata; pdata = pdev->dev.platform_data; if (!pdata) { dev_err(&pdev->dev, "no platform data supplied\n"); return -ENODEV; } r = platform_get_resource_byname(pdev, IORESOURCE_IO, "wdt-reg"); if (!r) { dev_err(&pdev->dev, "failed to get wdt-reg resource\n"); return -ENODEV; } rdc321x_wdt_device.sb_pdev = pdata->sb_pdev; rdc321x_wdt_device.base_reg = r->start; err = misc_register(&rdc321x_wdt_misc); if (err < 0) { dev_err(&pdev->dev, "misc_register failed\n"); return err; } spin_lock_init(&rdc321x_wdt_device.lock); /* */ pci_write_config_dword(rdc321x_wdt_device.sb_pdev, rdc321x_wdt_device.base_reg, RDC_WDT_RST); init_completion(&rdc321x_wdt_device.stop); rdc321x_wdt_device.queue = 0; clear_bit(0, &rdc321x_wdt_device.inuse); setup_timer(&rdc321x_wdt_device.timer, rdc321x_wdt_trigger, 0); rdc321x_wdt_device.default_ticks = ticks; dev_info(&pdev->dev, "watchdog init success\n"); return 0; } static int __devexit rdc321x_wdt_remove(struct platform_device *pdev) { if (rdc321x_wdt_device.queue) { rdc321x_wdt_device.queue = 0; wait_for_completion(&rdc321x_wdt_device.stop); } misc_deregister(&rdc321x_wdt_misc); return 0; } static struct platform_driver rdc321x_wdt_driver = { .probe = rdc321x_wdt_probe, .remove = __devexit_p(rdc321x_wdt_remove), .driver = { .owner = THIS_MODULE, .name = "rdc321x-wdt", }, }; module_platform_driver(rdc321x_wdt_driver); MODULE_AUTHOR("Florian Fainelli <*****@*****.**>"); MODULE_DESCRIPTION("RDC321x watchdog driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
static long mtx1_wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; int __user *p = (int __user *)argp; unsigned int value; static const struct watchdog_info ident = { .options = WDIOF_CARDRESET, .identity = "MTX-1 WDT", }; switch (cmd) { case WDIOC_GETSUPPORT: if (copy_to_user(argp, &ident, sizeof(ident))) return -EFAULT; break; case WDIOC_GETSTATUS: case WDIOC_GETBOOTSTATUS: put_user(0, p); break; case WDIOC_SETOPTIONS: if (get_user(value, p)) return -EFAULT; if (value & WDIOS_ENABLECARD) mtx1_wdt_start(); else if (value & WDIOS_DISABLECARD) mtx1_wdt_stop(); else return -EINVAL; return 0; case WDIOC_KEEPALIVE: mtx1_wdt_reset(); break; default: return -ENOTTY; } return 0; } static ssize_t mtx1_wdt_write(struct file *file, const char *buf, size_t count, loff_t *ppos) { if (!count) return -EIO; mtx1_wdt_reset(); return count; } static const struct file_operations mtx1_wdt_fops = { .owner = THIS_MODULE, .llseek = no_llseek, .unlocked_ioctl = mtx1_wdt_ioctl, .open = mtx1_wdt_open, .write = mtx1_wdt_write, .release = mtx1_wdt_release, }; static struct miscdevice mtx1_wdt_misc = { .minor = WATCHDOG_MINOR, .name = "watchdog", .fops = &mtx1_wdt_fops, }; static int __devinit mtx1_wdt_probe(struct platform_device *pdev) { int ret; mtx1_wdt_device.gpio = pdev->resource[0].start; ret = gpio_request_one(mtx1_wdt_device.gpio, GPIOF_OUT_INIT_HIGH, "mtx1-wdt"); if (ret < 0) { dev_err(&pdev->dev, "failed to request gpio"); return ret; } spin_lock_init(&mtx1_wdt_device.lock); init_completion(&mtx1_wdt_device.stop); mtx1_wdt_device.queue = 0; clear_bit(0, &mtx1_wdt_device.inuse); setup_timer(&mtx1_wdt_device.timer, mtx1_wdt_trigger, 0L); mtx1_wdt_device.default_ticks = ticks; ret = misc_register(&mtx1_wdt_misc); if (ret < 0) { dev_err(&pdev->dev, "failed to register\n"); return ret; } mtx1_wdt_start(); dev_info(&pdev->dev, "MTX-1 Watchdog driver\n"); return 0; } static int __devexit mtx1_wdt_remove(struct platform_device *pdev) { /* FIXME: do we need to lock this test ? */ if (mtx1_wdt_device.queue) { mtx1_wdt_device.queue = 0; wait_for_completion(&mtx1_wdt_device.stop); } gpio_free(mtx1_wdt_device.gpio); misc_deregister(&mtx1_wdt_misc); return 0; } static struct platform_driver mtx1_wdt_driver = { .probe = mtx1_wdt_probe, .remove = __devexit_p(mtx1_wdt_remove), .driver.name = "mtx1-wdt", .driver.owner = THIS_MODULE, }; module_platform_driver(mtx1_wdt_driver); MODULE_AUTHOR("Michael Stickel, Florian Fainelli"); MODULE_DESCRIPTION("Driver for the MTX-1 watchdog"); MODULE_LICENSE("GPL"); MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR); MODULE_ALIAS("platform:mtx1-wdt");
static int ixp4xx_flash_probe(struct platform_device *dev) { struct flash_platform_data *plat = dev_get_platdata(&dev->dev); struct ixp4xx_flash_info *info; struct mtd_part_parser_data ppdata = { .origin = dev->resource->start, }; int err = -1; if (!plat) return -ENODEV; if (plat->init) { err = plat->init(); if (err) return err; } info = devm_kzalloc(&dev->dev, sizeof(struct ixp4xx_flash_info), GFP_KERNEL); if(!info) { err = -ENOMEM; goto Error; } platform_set_drvdata(dev, info); /* * Tell the MTD layer we're not 1:1 mapped so that it does * not attempt to do a direct access on us. */ info->map.phys = NO_XIP; info->map.size = resource_size(dev->resource); /* * We only support 16-bit accesses for now. If and when * any board use 8-bit access, we'll fixup the driver to * handle that. */ info->map.bankwidth = 2; info->map.name = dev_name(&dev->dev); info->map.read = ixp4xx_read16; info->map.write = ixp4xx_probe_write16; info->map.copy_from = ixp4xx_copy_from; info->map.virt = devm_ioremap_resource(&dev->dev, dev->resource); if (IS_ERR(info->map.virt)) { err = PTR_ERR(info->map.virt); goto Error; } info->mtd = do_map_probe(plat->map_name, &info->map); if (!info->mtd) { printk(KERN_ERR "IXP4XXFlash: map_probe failed\n"); err = -ENXIO; goto Error; } info->mtd->owner = THIS_MODULE; /* Use the fast version */ info->map.write = ixp4xx_write16; err = mtd_device_parse_register(info->mtd, probes, &ppdata, plat->parts, plat->nr_parts); if (err) { printk(KERN_ERR "Could not parse partitions\n"); goto Error; } return 0; Error: ixp4xx_flash_remove(dev); return err; } static struct platform_driver ixp4xx_flash_driver = { .probe = ixp4xx_flash_probe, .remove = ixp4xx_flash_remove, .driver = { .name = "IXP4XX-Flash", .owner = THIS_MODULE, }, }; module_platform_driver(ixp4xx_flash_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("MTD map driver for Intel IXP4xx systems"); MODULE_AUTHOR("Deepak Saxena"); MODULE_ALIAS("platform:IXP4XX-Flash");
static int axp20x_regulator_probe(struct platform_device *pdev) { struct regulator_dev *rdev; struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent); const struct regulator_desc *regulators; struct regulator_config config = { .dev = pdev->dev.parent, .regmap = axp20x->regmap, .driver_data = axp20x, }; int ret, i, nregulators; u32 workmode; const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name; const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name; bool drivevbus = false; switch (axp20x->variant) { case AXP202_ID: case AXP209_ID: regulators = axp20x_regulators; nregulators = AXP20X_REG_ID_MAX; break; case AXP221_ID: case AXP223_ID: regulators = axp22x_regulators; nregulators = AXP22X_REG_ID_MAX; drivevbus = of_property_read_bool(pdev->dev.parent->of_node, "x-powers,drive-vbus-en"); break; case AXP809_ID: regulators = axp809_regulators; nregulators = AXP809_REG_ID_MAX; break; default: dev_err(&pdev->dev, "Unsupported AXP variant: %ld\n", axp20x->variant); return -EINVAL; } /* This only sets the dcdc freq. Ignore any errors */ axp20x_regulator_parse_dt(pdev); for (i = 0; i < nregulators; i++) { const struct regulator_desc *desc = ®ulators[i]; struct regulator_desc *new_desc; /* * Regulators DC1SW and DC5LDO are connected internally, * so we have to handle their supply names separately. * * We always register the regulators in proper sequence, * so the supply names are correctly read. See the last * part of this loop to see where we save the DT defined * name. */ if ((regulators == axp22x_regulators && i == AXP22X_DC1SW) || (regulators == axp809_regulators && i == AXP809_DC1SW)) { new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL); *new_desc = regulators[i]; new_desc->supply_name = dcdc1_name; desc = new_desc; } if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) || (regulators == axp809_regulators && i == AXP809_DC5LDO)) { new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), GFP_KERNEL); *new_desc = regulators[i]; new_desc->supply_name = dcdc5_name; desc = new_desc; } rdev = devm_regulator_register(&pdev->dev, desc, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register %s\n", regulators[i].name); return PTR_ERR(rdev); } ret = of_property_read_u32(rdev->dev.of_node, "x-powers,dcdc-workmode", &workmode); if (!ret) { if (axp20x_set_dcdc_workmode(rdev, i, workmode)) dev_err(&pdev->dev, "Failed to set workmode on %s\n", rdev->desc->name); } /* * Save AXP22X DCDC1 / DCDC5 regulator names for later. */ if ((regulators == axp22x_regulators && i == AXP22X_DCDC1) || (regulators == axp809_regulators && i == AXP809_DCDC1)) of_property_read_string(rdev->dev.of_node, "regulator-name", &dcdc1_name); if ((regulators == axp22x_regulators && i == AXP22X_DCDC5) || (regulators == axp809_regulators && i == AXP809_DCDC5)) of_property_read_string(rdev->dev.of_node, "regulator-name", &dcdc5_name); } if (drivevbus) { /* Change N_VBUSEN sense pin to DRIVEVBUS output pin */ regmap_update_bits(axp20x->regmap, AXP20X_OVER_TMP, AXP22X_MISC_N_VBUSEN_FUNC, 0); rdev = devm_regulator_register(&pdev->dev, &axp22x_drivevbus_regulator, &config); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "Failed to register drivevbus\n"); return PTR_ERR(rdev); } } return 0; } static struct platform_driver axp20x_regulator_driver = { .probe = axp20x_regulator_probe, .driver = { .name = "axp20x-regulator", }, }; module_platform_driver(axp20x_regulator_driver); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Carlo Caione <*****@*****.**>"); MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC"); MODULE_ALIAS("platform:axp20x-regulator");
/* * sysfs hook function */ static ssize_t madc_read(struct device *dev, struct device_attribute *devattr, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); struct twl4030_madc_request req = { .channels = 1 << attr->index, .method = TWL4030_MADC_SW2, .type = TWL4030_MADC_WAIT, }; long val; val = twl4030_madc_conversion(&req); if (val < 0) return val; return sprintf(buf, "%d\n", req.rbuf[attr->index]); } /* sysfs nodes to read individual channels from user side */ static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, madc_read, NULL, 0); static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, madc_read, NULL, 1); static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, madc_read, NULL, 2); static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, madc_read, NULL, 3); static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, madc_read, NULL, 4); static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, madc_read, NULL, 5); static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, madc_read, NULL, 6); static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, madc_read, NULL, 7); static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, madc_read, NULL, 8); static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, madc_read, NULL, 9); static SENSOR_DEVICE_ATTR(curr10_input, S_IRUGO, madc_read, NULL, 10); static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11); static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12); static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15); static struct attribute *twl4030_madc_attrs[] = { &sensor_dev_attr_in0_input.dev_attr.attr, &sensor_dev_attr_temp1_input.dev_attr.attr, &sensor_dev_attr_in2_input.dev_attr.attr, &sensor_dev_attr_in3_input.dev_attr.attr, &sensor_dev_attr_in4_input.dev_attr.attr, &sensor_dev_attr_in5_input.dev_attr.attr, &sensor_dev_attr_in6_input.dev_attr.attr, &sensor_dev_attr_in7_input.dev_attr.attr, &sensor_dev_attr_in8_input.dev_attr.attr, &sensor_dev_attr_in9_input.dev_attr.attr, &sensor_dev_attr_curr10_input.dev_attr.attr, &sensor_dev_attr_in11_input.dev_attr.attr, &sensor_dev_attr_in12_input.dev_attr.attr, &sensor_dev_attr_in15_input.dev_attr.attr, NULL }; ATTRIBUTE_GROUPS(twl4030_madc); static int twl4030_madc_hwmon_probe(struct platform_device *pdev) { struct device *hwmon; hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "twl4030_madc", NULL, twl4030_madc_groups); return PTR_ERR_OR_ZERO(hwmon); } static struct platform_driver twl4030_madc_hwmon_driver = { .probe = twl4030_madc_hwmon_probe, .driver = { .name = "twl4030_madc_hwmon", .owner = THIS_MODULE, }, }; module_platform_driver(twl4030_madc_hwmon_driver); MODULE_DESCRIPTION("TWL4030 ADC Hwmon driver"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("J Keerthy"); MODULE_ALIAS("platform:twl4030_madc_hwmon");
static int micro_bl_update_status(struct backlight_device *bd) { struct ipaq_micro *micro = dev_get_drvdata(&bd->dev); int intensity = bd->props.brightness; struct ipaq_micro_msg msg = { .id = MSG_BACKLIGHT, .tx_len = 3, }; if (bd->props.power != FB_BLANK_UNBLANK) intensity = 0; if (bd->props.state & (BL_CORE_FBBLANK | BL_CORE_SUSPENDED)) intensity = 0; /* * Message format: * Byte 0: backlight instance (usually 1) * Byte 1: on/off * Byte 2: intensity, 0-255 */ msg.tx_data[0] = 0x01; msg.tx_data[1] = intensity > 0 ? 1 : 0; msg.tx_data[2] = intensity; return ipaq_micro_tx_msg_sync(micro, &msg); } static const struct backlight_ops micro_bl_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = micro_bl_update_status, }; static struct backlight_properties micro_bl_props = { .type = BACKLIGHT_RAW, .max_brightness = 255, .power = FB_BLANK_UNBLANK, .brightness = 64, }; static int micro_backlight_probe(struct platform_device *pdev) { struct backlight_device *bd; struct ipaq_micro *micro = dev_get_drvdata(pdev->dev.parent); bd = devm_backlight_device_register(&pdev->dev, "ipaq-micro-backlight", &pdev->dev, micro, µ_bl_ops, µ_bl_props); if (IS_ERR(bd)) return PTR_ERR(bd); platform_set_drvdata(pdev, bd); backlight_update_status(bd); return 0; } static struct platform_driver micro_backlight_device_driver = { .driver = { .name = "ipaq-micro-backlight", }, .probe = micro_backlight_probe, }; module_platform_driver(micro_backlight_device_driver); MODULE_LICENSE("GPL v2"); MODULE_DESCRIPTION("driver for iPAQ Atmel micro backlight"); MODULE_ALIAS("platform:ipaq-micro-backlight");
static int micro_leds_brightness_set(struct led_classdev *led_cdev, enum led_brightness value) { struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent); /* * In this message: * Byte 0 = LED color: 0 = yellow, 1 = green * yellow LED is always ~30 blinks per minute * Byte 1 = duration (flags?) appears to be ignored * Byte 2 = green ontime in 1/10 sec (deciseconds) * 1 = 1/10 second * 0 = 256/10 second * Byte 3 = green offtime in 1/10 sec (deciseconds) * 1 = 1/10 second * 0 = 256/10 seconds */ struct ipaq_micro_msg msg = { .id = MSG_NOTIFY_LED, .tx_len = 4, }; msg.tx_data[0] = LED_GREEN; msg.tx_data[1] = 0; if (value) { msg.tx_data[2] = 0; /* Duty cycle 256 */ msg.tx_data[3] = 1; } else { msg.tx_data[2] = 1; msg.tx_data[3] = 0; /* Duty cycle 256 */ } return ipaq_micro_tx_msg_sync(micro, &msg); } /* Maximum duty cycle in ms 256/10 sec = 25600 ms */ #define IPAQ_LED_MAX_DUTY 25600 static int micro_leds_blink_set(struct led_classdev *led_cdev, unsigned long *delay_on, unsigned long *delay_off) { struct ipaq_micro *micro = dev_get_drvdata(led_cdev->dev->parent->parent); /* * In this message: * Byte 0 = LED color: 0 = yellow, 1 = green * yellow LED is always ~30 blinks per minute * Byte 1 = duration (flags?) appears to be ignored * Byte 2 = green ontime in 1/10 sec (deciseconds) * 1 = 1/10 second * 0 = 256/10 second * Byte 3 = green offtime in 1/10 sec (deciseconds) * 1 = 1/10 second * 0 = 256/10 seconds */ struct ipaq_micro_msg msg = { .id = MSG_NOTIFY_LED, .tx_len = 4, }; msg.tx_data[0] = LED_GREEN; if (*delay_on > IPAQ_LED_MAX_DUTY || *delay_off > IPAQ_LED_MAX_DUTY) return -EINVAL; if (*delay_on == 0 && *delay_off == 0) { *delay_on = 100; *delay_off = 100; } msg.tx_data[1] = 0; if (*delay_on >= IPAQ_LED_MAX_DUTY) msg.tx_data[2] = 0; else msg.tx_data[2] = (u8) DIV_ROUND_CLOSEST(*delay_on, 100); if (*delay_off >= IPAQ_LED_MAX_DUTY) msg.tx_data[3] = 0; else msg.tx_data[3] = (u8) DIV_ROUND_CLOSEST(*delay_off, 100); return ipaq_micro_tx_msg_sync(micro, &msg); } static struct led_classdev micro_led = { .name = "led-ipaq-micro", .brightness_set_blocking = micro_leds_brightness_set, .blink_set = micro_leds_blink_set, .flags = LED_CORE_SUSPENDRESUME, }; static int micro_leds_probe(struct platform_device *pdev) { int ret; ret = devm_led_classdev_register(&pdev->dev, µ_led); if (ret) { dev_err(&pdev->dev, "registering led failed: %d\n", ret); return ret; } dev_info(&pdev->dev, "iPAQ micro notification LED driver\n"); return 0; } static struct platform_driver micro_leds_device_driver = { .driver = { .name = "ipaq-micro-leds", }, .probe = micro_leds_probe, }; module_platform_driver(micro_leds_device_driver); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("driver for iPAQ Atmel micro leds"); MODULE_ALIAS("platform:ipaq-micro-leds");