static int vib_signal_init(struct vib_signal *vibs) { struct vib_of_signal *of = &vibs->of; int ret; switch (of->type) { case SIGNAL_GPIO: ret = vib_ctrl_gpio_init(vibs); vibs->ops = &vib_ctrl_gpio_ops; break; default: zfprintk("%s unknown signal type %d\n", vibs->name, of->type); of->type = 0; ret = -1; } return ret; }
static int vib_ctrl_gpio_activate(struct vib_signal *vibs) { struct vib_ctrl_gpio *gpioc = &vibs->gpioc; struct vib_of_signal *of = &vibs->of; int ret; dvib_tprint("g+ %s\n", vibs->name); if (!gpioc->active_us) return 0; ret = gpio_direction_output(of->gpio, of->active_level); if (ret) { zfprintk("gpio %d output %d failed %d\n", of->gpio, of->active_level, ret); return ret; } gpioc->stage = GPIO_STAGE_ACTIVE; ret = hrtimer_start(&gpioc->hrtimer, ns_to_ktime((u64) gpioc->active_us * NSEC_PER_USEC), HRTIMER_MODE_REL); if (ret) dvib_tprint("started timer %p while active.\n", &gpioc->hrtimer); return 0; }
void __init mmi_vibrator_init(void) { int i, count; struct vibrator *vib; struct vib_timed *vib_timed; for (i = 0, count = 0; i < MAX_VIBS; i++) { vib = &vibrators[count]; vib_timed = &vib_timeds[count]; if (vib_of_init(vib, i)) { zfprintk("DT vibrator settings not found," " using defaults\n"); if (vib_of_init_default(vib, i)) continue; } vib_timed->dev_data = vib; vib_timed->min_timeout = vib->min_us / USEC_PER_MSEC; vib_timed->max_timeout = vib->max_us / USEC_PER_MSEC; vib_timed->init = vibrator_init; vib_timed->exit = vibrator_exit; vib_timed->power_on = vibrator_power_on; vib_timed->power_off = vibrator_power_off; vib_timed->dump = vibrator_dump; vib_timed->name = vib_name[count]; wake_lock_init(&vib->wakelock, WAKE_LOCK_SUSPEND, vib_timed->name); count++; dprintk("%s type 0x%x min %d max %d\n", vib_timed->name, vib->type, vib_timed->min_timeout, vib_timed->max_timeout); } if (count) { vib_timed_pdata.count = count; platform_device_register(&vib_timed_dev); } }
static int vib_of_init(struct vibrator *vib, int vib_nr) { struct device_node *node; const void *prop = NULL; int len = 0; char dt_path_vib[sizeof(DT_PATH_VIB) + 3]; snprintf(dt_path_vib, sizeof(DT_PATH_VIB) + 2, "%s%1d", DT_PATH_VIB, vib_nr % MAX_VIBS); node = of_find_node_by_path(dt_path_vib); if (!node) return -ENODEV; prop = of_get_property(node, DT_PROP_VIB_TYPE, &len); if (prop && len) vib->type = *((int *)prop); else return -ENODEV; if ((vib->type != VIB_TYPE_GENENIC_ROTARY) && (vib->type != VIB_TYPE_GENENIC_LINEAR)) return -ENODEV; prop = of_get_property(node, VIB_EN, &len); if (prop && len) { vib->ctrl.vib_en.of = *((struct vib_of_signal *)prop); vib->ctrl.vib_en.name = VIB_EN; vib->ctrl.vib_en.signal_type = SIGNAL_ENABLE; if (vib_signal_init(&vib->ctrl.vib_en)) { zfprintk("vib_en init failed\n"); return -ENODEV; } } else { zfprintk("vib_en not found in %s\n", dt_path_vib); return -ENODEV; } prop = of_get_property(node, "pwm", &len); if (prop && len) { int i, j = len / sizeof(struct vib_pwm); dprintk("pwm len %d size %d\n", len, len/sizeof(struct vib_pwm)); if (j > MAX_PWMS) j = MAX_PWMS; for (i = 0; i < j; i++) vib->ctrl.vib_pwm[i] = *(((struct vib_pwm *)prop) + i); } else { zfprintk("pwm not found in %s\n", dt_path_vib); return -ENODEV; } prop = of_get_property(node, VIB_DIR, &len); if (prop && len) { vib->ctrl.vib_dir.of = *((struct vib_of_signal *)prop); vib->ctrl.vib_dir.name = VIB_DIR; vib->ctrl.vib_dir.signal_type = SIGNAL_DIRECTION; if (vib_signal_init(&vib->ctrl.vib_dir)) { zfprintk("vib_dir init failed\n"); return -ENODEV; } } else { if (vib->type == VIB_TYPE_GENENIC_LINEAR) { zfprintk("vib_dir not found in %s\n", dt_path_vib); return -ENODEV; } } prop = of_get_property(node, "regulator", &len); if (prop && len) { strncpy(vib->reg.name, (char *)prop, REGULATOR_NAME_SIZE - 1); vib->reg.name[REGULATOR_NAME_SIZE - 1] = '\0'; prop = of_get_property(node, "deferred_off", &len); if (prop && len) { vib->reg.deferred_off = *(u32 *)prop; zfprintk("deferred_off %u\n", vib->reg.deferred_off); } vib->reg.volt[0].time = MAX_TIMEOUT; vib->reg.volt[0].min_uV = 2800000; vib->reg.volt[0].max_uV = 2800000; prop = of_get_property(node, "voltage", &len); if (prop && len) { int i, j = len / sizeof(struct vib_voltage); dprintk("voltage len %d size %d\n", len, len/sizeof(struct vib_voltage)); if (j > MAX_VOLT) j = MAX_VOLT; for (i = 0; i < j; i++) vib->reg.volt[i] = *(((struct vib_voltage *)prop) + i); } } prop = of_get_property(node, "min", &len); if (prop && len) vib->min_us = *((unsigned int *)prop); else vib->min_us = MIN_TIMEOUT; prop = of_get_property(node, "max", &len); if (prop && len) vib->max_us = *((unsigned int *)prop); else vib->max_us = MAX_TIMEOUT; of_node_put(node); return 0; }
static int vib_of_init(struct vibrator *vib, int vib_nr) { struct device_node *node; const void *prop = NULL; const char *name; int len = 0 ; char dt_path_vib[sizeof(DT_PATH_VIB) + 3]; snprintf(dt_path_vib, sizeof(DT_PATH_VIB) + 2, "%s%1d", DT_PATH_VIB, vib_nr % MAX_VIBS); node = of_find_node_by_path(dt_path_vib); if (!node) return -ENODEV; if (of_property_read_u32(node, DT_PROP_VIB_TYPE, &vib->type)) { zfprintk("DT vibrator type read error\n"); return -ENODEV; } if ((vib->type != VIB_TYPE_GENENIC_ROTARY) && (vib->type != VIB_TYPE_GENENIC_LINEAR)) return -ENODEV; if (of_property_read_u32_array(node, VIB_EN, (u32 *)(&vib->ctrl.vib_en.of), 4)) { zfprintk("DT vibrator VIB_EN settings read error\n"); return -ENODEV; } vib->ctrl.vib_en.name = VIB_EN; vib->ctrl.vib_en.signal_type = SIGNAL_ENABLE; if (vib_signal_init(&vib->ctrl.vib_en)) { zfprintk("vib_en init failed\n"); return -ENODEV; } prop = of_get_property(node, "pwm", &len); if (prop && len) { int j = len / sizeof(struct vib_pwm); if (j > MAX_PWMS) j = MAX_PWMS; if (of_property_read_u32_array(node, "pwm", (u32 *)(&vib->ctrl.vib_pwm), j*4)) { zfprintk("DT vibrator PWM settings read error\n"); return -ENODEV; } } else { zfprintk("pwm not found in %s\n", dt_path_vib); return -ENODEV; } if (of_property_read_u32_array(node, VIB_DIR, (u32 *)(&vib->ctrl.vib_dir.of), 4)) { zfprintk("DT vibrator VIB_DIR settings read error\n"); if (vib->type == VIB_TYPE_GENENIC_LINEAR) { zfprintk("vib_dir not found in %s\n", dt_path_vib); return -ENODEV; } } else { vib->ctrl.vib_dir.name = VIB_DIR; vib->ctrl.vib_dir.signal_type = SIGNAL_DIRECTION; if (vib_signal_init(&vib->ctrl.vib_dir)) { zfprintk("vib_dir init failed\n"); return -ENODEV; } } if (!of_property_read_string(node, "regulator", &name)) { strlcpy(vib->reg.name, name, sizeof(vib->reg.name)); of_property_read_u32(node, "deferred_off", &vib->reg.deferred_off); vib->reg.volt[0].time = MAX_TIMEOUT; vib->reg.volt[0].min_uV = 2800000; vib->reg.volt[0].max_uV = 2800000; prop = of_get_property(node, "voltage", &len); if (prop && len) { int j = len / sizeof(struct vib_voltage); if (j > MAX_VOLT) j = MAX_VOLT; of_property_read_u32_array(node, "voltage", (u32 *)(&vib->reg.volt), j*3); } } if (of_property_read_u32(node, "min", &vib->min_us)) vib->min_us = MIN_TIMEOUT; if (of_property_read_u32(node, "max", &vib->max_us)) vib->max_us = MAX_TIMEOUT; of_node_put(node); return 0; }