static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi) { struct qpnp_vib *vib; const __be32 *temp_dt; struct resource *vib_resource; int rc; u8 val; vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL); if (!vib) return -ENOMEM; vib->spmi = spmi; temp_dt = of_get_property(spmi->dev.of_node, "qcom,qpnp-vib-timeout-ms", NULL); if (temp_dt) vib->timeout = be32_to_cpu(*temp_dt); else vib->timeout = QPNP_VIB_DEFAULT_TIMEOUT; temp_dt = of_get_property(spmi->dev.of_node, "qcom,qpnp-vib-vtg-level-mV", NULL); if (temp_dt) vib->vtg_level = be32_to_cpu(*temp_dt); else vib->vtg_level = QPNP_VIB_DEFAULT_VTG_LVL; vib->vtg_level /= 100; vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0); if (!vib_resource) { dev_err(&spmi->dev, "Unable to get vibrator base address\n"); return -EINVAL; } vib->base = vib_resource->start; rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) return rc; vib->reg_vtg_ctl = val; rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) return rc; vib->reg_en_ctl = val; spin_lock_init(&vib->lock); INIT_WORK(&vib->work, qpnp_vib_update); hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); vib->vib_timer.function = qpnp_vib_timer_func; vib->timed_dev.name = "vibrator"; vib->timed_dev.get_time = qpnp_vib_get_time; vib->timed_dev.enable = qpnp_vib_enable; dev_set_drvdata(&spmi->dev, vib); rc = timed_output_dev_register(&vib->timed_dev); if (rc < 0) return rc; #ifdef CONFIG_VIB_TRIGGERS vib->enabler.name = "qpnp-vibrator"; vib->enabler.default_trigger = "vibrator"; vib->enabler.enable = qpnp_vib_trigger_enable; vib->enabler.trigger_data = vib; vib_trigger_enabler_register(&vib->enabler); #endif vib_dev = vib; return rc; }
static int qpnp_vibrator_probe(struct spmi_device *spmi) { struct qpnp_vib *vib; struct resource *vib_resource; int rc; printk(KERN_INFO "[VIB] %s\n", __func__); vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL); if (!vib) return -ENOMEM; vib->spmi = spmi; vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0); if (!vib_resource) { dev_err(&spmi->dev, "Unable to get vibrator base address\n"); return -EINVAL; } vib->base = vib_resource->start; rc = qpnp_vib_parse_dt(vib); if (rc) { dev_err(&spmi->dev, "DT parsing failed\n"); return rc; } rc = qpnp_vibrator_config(vib); if (rc) { dev_err(&spmi->dev, "vib config failed\n"); return rc; } mutex_init(&vib->lock); INIT_WORK(&vib->work, qpnp_vib_update); hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); vib->vib_timer.function = qpnp_vib_timer_func; vib->timed_dev.name = "vibrator"; vib->timed_dev.get_time = qpnp_vib_get_time; vib->timed_dev.enable = qpnp_vib_enable; dev_set_drvdata(&spmi->dev, vib); rc = timed_output_dev_register(&vib->timed_dev); if (rc < 0) return rc; rc = device_create_file(vib->timed_dev.dev, &dev_attr_voltage_level); if (rc < 0) { printk(KERN_INFO "[VIB] %s, create sysfs fail: voltage_level\n", __func__); } #ifdef CONFIG_VIB_TRIGGERS vib->enabler.name = "qpnp-vibrator"; vib->enabler.default_trigger = "vibrator"; vib->enabler.enable = qpnp_vib_trigger_enable; vib->enabler.trigger_data = vib; vib_trigger_enabler_register(&vib->enabler); #endif return rc; }