/* Fill in pdata elements based on values found in device tree. */ static int qpnp_regulator_get_dt_config(struct spmi_device *spmi, struct qpnp_regulator_platform_data *pdata) { struct resource *res; struct device_node *node = spmi->dev.of_node; int rc = 0; pdata->init_data.constraints.input_uV = pdata->init_data.constraints.max_uV; res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!res) { dev_err(&spmi->dev, "%s: node is missing base address\n", __func__); return -EINVAL; } pdata->base_addr = res->start; /* * Initialize configuration parameters to use hardware default in case * no value is specified via device tree. */ pdata->auto_mode_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->bypass_mode_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->ocp_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->pull_down_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->soft_start_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->boost_current_limit = QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT; pdata->pin_ctrl_enable = QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT; pdata->pin_ctrl_hpm = QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT; pdata->vs_soft_start_strength = QPNP_VS_SOFT_START_STR_HW_DEFAULT; /* These bindings are optional, so it is okay if they are not found. */ of_property_read_u32(node, "qcom,auto-mode-enable", &pdata->auto_mode_enable); of_property_read_u32(node, "qcom,bypass-mode-enable", &pdata->bypass_mode_enable); of_property_read_u32(node, "qcom,ocp-enable", &pdata->ocp_enable); of_property_read_u32(node, "qcom,pull-down-enable", &pdata->pull_down_enable); of_property_read_u32(node, "qcom,soft-start-enable", &pdata->soft_start_enable); of_property_read_u32(node, "qcom,boost-current-limit", &pdata->boost_current_limit); of_property_read_u32(node, "qcom,pin-ctrl-enable", &pdata->pin_ctrl_enable); of_property_read_u32(node, "qcom,pin-ctrl-hpm", &pdata->pin_ctrl_hpm); of_property_read_u32(node, "qcom,vs-soft-start-strength", &pdata->vs_soft_start_strength); of_property_read_u32(node, "qcom,system-load", &pdata->system_load); of_property_read_u32(node, "qcom,enable-time", &pdata->enable_time); of_property_read_u32(node, "qcom,ocp-enable-time", &pdata->ocp_enable_time); return rc; }
static int qpnp_vibrator_probe(struct spmi_device *spmi) { struct qpnp_vib *vib; struct resource *vib_resource; int rc; 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; device_create_file(vib->timed_dev.dev, &dev_attr_vtg_level); return rc; }
static int bcl_get_devicetree_data(struct spmi_device *spmi) { int ret = 0, irq_num = 0, temp_val = 0; struct resource *resource = NULL; char *key = NULL; const __be32 *prop = NULL; struct device_node *dev_node = spmi->dev.of_node; /* Get SPMI peripheral address */ resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!resource) { pr_err("No base address defined\n"); return -EINVAL; } bcl_perph->slave_id = spmi->sid; prop = of_get_address_by_name(dev_node, "fg_user_adc", 0, 0); if (prop) { bcl_perph->base_addr = be32_to_cpu(*prop); pr_debug("fg_user_adc@%04x\n", bcl_perph->base_addr); } else { dev_err(&spmi->dev, "No fg_user_adc registers found\n"); return -EINVAL; } prop = of_get_address_by_name(dev_node, "pon_spare", 0, 0); if (prop) { bcl_perph->pon_spare_addr = be32_to_cpu(*prop); pr_debug("pon_spare@%04x\n", bcl_perph->pon_spare_addr); } /* Register SPMI peripheral interrupt */ irq_num = spmi_get_irq_byname(spmi, NULL, BCL_VBAT_INT_NAME); if (irq_num < 0) { pr_err("Invalid vbat IRQ\n"); ret = -ENXIO; goto bcl_dev_exit; } bcl_perph->param[BCL_PARAM_VOLTAGE].irq_num = irq_num; irq_num = spmi_get_irq_byname(spmi, NULL, BCL_IBAT_INT_NAME); if (irq_num < 0) { pr_err("Invalid ibat IRQ\n"); ret = -ENXIO; goto bcl_dev_exit; } bcl_perph->param[BCL_PARAM_CURRENT].irq_num = irq_num; /* Get VADC and IADC scaling factor */ key = "qcom,vbat-scaling-factor"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_VOLTAGE].scaling_factor); key = "qcom,vbat-gain-numerator"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_VOLTAGE].gain_factor_num); key = "qcom,vbat-gain-denominator"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_VOLTAGE].gain_factor_den); key = "qcom,ibat-scaling-factor"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].scaling_factor); key = "qcom,ibat-offset-numerator"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].offset_factor_num); key = "qcom,ibat-offset-denominator"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].offset_factor_den); key = "qcom,ibat-gain-numerator"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].gain_factor_num); key = "qcom,ibat-gain-denominator"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].gain_factor_den); key = "qcom,vbat-polling-delay-ms"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_VOLTAGE].polling_delay_ms); key = "qcom,ibat-polling-delay-ms"; READ_CONV_FACTOR(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].polling_delay_ms); key = "qcom,inhibit-derating-ua"; READ_OPTIONAL_PROP(dev_node, key, temp_val, ret, bcl_perph->param[BCL_PARAM_CURRENT].inhibit_derating_ua); bcl_dev_exit: return ret; }
static int qpnp_haptic_probe(struct spmi_device *spmi) { struct qpnp_hap *hap; struct resource *hap_resource; int rc, i; hap = devm_kzalloc(&spmi->dev, sizeof(*hap), GFP_KERNEL); if (!hap) return -ENOMEM; hap->spmi = spmi; hap_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0); if (!hap_resource) { dev_err(&spmi->dev, "Unable to get haptic base address\n"); return -EINVAL; } hap->base = hap_resource->start; dev_set_drvdata(&spmi->dev, hap); rc = qpnp_hap_parse_dt(hap); if (rc) { dev_err(&spmi->dev, "DT parsing failed\n"); return rc; } rc = qpnp_hap_config(hap); if (rc) { dev_err(&spmi->dev, "hap config failed\n"); return rc; } mutex_init(&hap->lock); mutex_init(&hap->wf_lock); INIT_WORK(&hap->work, qpnp_hap_worker); hrtimer_init(&hap->hap_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hap->hap_timer.function = qpnp_hap_timer; hap->timed_dev.name = "vibrator"; hap->timed_dev.get_time = qpnp_hap_get_time; hap->timed_dev.enable = qpnp_hap_td_enable; rc = timed_output_dev_register(&hap->timed_dev); if (rc < 0) { dev_err(&spmi->dev, "timed_output registration failed\n"); goto timed_output_fail; } for (i = 0; i < ARRAY_SIZE(qpnp_hap_attrs); i++) { rc = sysfs_create_file(&hap->timed_dev.dev->kobj, &qpnp_hap_attrs[i].attr); if (rc < 0) { dev_err(&spmi->dev, "sysfs creation failed\n"); goto sysfs_fail; } } return 0; sysfs_fail: for (i--; i >= 0; i--) sysfs_remove_file(&hap->timed_dev.dev->kobj, &qpnp_hap_attrs[i].attr); timed_output_dev_unregister(&hap->timed_dev); timed_output_fail: cancel_work_sync(&hap->work); hrtimer_cancel(&hap->hap_timer); mutex_destroy(&hap->lock); mutex_destroy(&hap->wf_lock); return rc; }
static int qpnp_typec_probe(struct spmi_device *spmi) { int rc; struct resource *resource; struct qpnp_typec_chip *chip; resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!resource) { pr_err("Unable to get spmi resource for TYPEC\n"); return -EINVAL; } chip = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_typec_chip), GFP_KERNEL); if (!chip) return -ENOMEM; chip->dev = &spmi->dev; chip->spmi = spmi; /* parse DT */ rc = qpnp_typec_parse_dt(chip); if (rc) { pr_err("failed to parse DT rc=%d\n", rc); return rc; } chip->base = resource->start; dev_set_drvdata(&spmi->dev, chip); device_init_wakeup(&spmi->dev, 1); mutex_init(&chip->typec_lock); /* determine initial status */ rc = qpnp_typec_determine_initial_status(chip); if (rc) { pr_err("failed to determine initial state rc=%d\n", rc); return rc; } chip->type_c_psy.name = TYPEC_PSY_NAME; chip->type_c_psy.get_property = qpnp_typec_get_property; chip->type_c_psy.properties = qpnp_typec_properties; chip->type_c_psy.num_properties = ARRAY_SIZE(qpnp_typec_properties); rc = power_supply_register(chip->dev, &chip->type_c_psy); if (rc < 0) { pr_err("Unable to register type_c_psy rc=%d\n", rc); return rc; } /* All irqs */ rc = qpnp_typec_request_irqs(chip); if (rc) { pr_err("failed to request irqs rc=%d\n", rc); return rc; } pr_info("TypeC successfully probed state=%d CC-line-state=%d\n", chip->typec_state, chip->cc_line_state); return 0; }
static int __devinit qpnp_pon_probe(struct spmi_device *spmi) { struct qpnp_pon *pon; struct resource *pon_resource; struct device_node *itr = NULL; u32 delay = 0; int rc, sys_reset; struct device *sec_powerkey; #ifdef CONFIG_SEC_PM struct device *sec_power; #endif int ret; pon = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_pon), GFP_KERNEL); if (!pon) { dev_err(&spmi->dev, "Can't allocate qpnp_pon\n"); return -ENOMEM; } sys_reset = of_property_read_bool(spmi->dev.of_node, "qcom,system-reset"); if (sys_reset && sys_reset_dev) { dev_err(&spmi->dev, "qcom,system-reset property can only be specified for one device on the system\n"); return -EINVAL; } else if (sys_reset) { sys_reset_dev = pon; } pon->spmi = spmi; /* get the total number of pon configurations */ while ((itr = of_get_next_child(spmi->dev.of_node, itr))) pon->num_pon_config++; if (!pon->num_pon_config) { /* No PON config., do not register the driver */ dev_err(&spmi->dev, "No PON config. specified\n"); return -EINVAL; } pon->pon_cfg = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_pon_config) * pon->num_pon_config, GFP_KERNEL); pon_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!pon_resource) { dev_err(&spmi->dev, "Unable to get PON base address\n"); return -ENXIO; } pon->base = pon_resource->start; rc = of_property_read_u32(pon->spmi->dev.of_node, "qcom,pon-dbc-delay", &delay); if (rc) { if (rc != -EINVAL) { dev_err(&spmi->dev, "Unable to read debounce delay\n"); return rc; } } else { delay = (delay << QPNP_PON_DELAY_BIT_SHIFT) / USEC_PER_SEC; delay = ilog2(delay); rc = qpnp_pon_masked_write(pon, QPNP_PON_DBC_CTL(pon->base), QPNP_PON_DBC_DELAY_MASK, delay); if (rc) { dev_err(&spmi->dev, "Unable to set PON debounce\n"); return rc; } } dev_set_drvdata(&spmi->dev, pon); INIT_DELAYED_WORK(&pon->bark_work, bark_work_func); /* register the PON configurations */ rc = qpnp_pon_config_init(pon); if (rc) { dev_err(&spmi->dev, "Unable to intialize PON configurations\n"); return rc; } #ifdef CONFIG_CONTROL_S2_RESET if (0 == sec_debug_is_enabled()) qpnp_control_s2_reset(0); #endif #ifdef CONFIG_SEC_PM qpnp_control_s3_reset_timer(); sec_power = device_create(sec_class, NULL, 0, NULL, "sec_power"); if (IS_ERR(sec_power)) pr_err("Failed to create device(sec_power)!\n"); ret = device_create_file(sec_power, &dev_attr_enable_hw_reset); if (ret) { pr_err("Failed to create device file in sysfs entries(%s)!\n", dev_attr_enable_hw_reset.attr.name); } dev_set_drvdata(sec_power, pon); #endif sec_powerkey = device_create(sec_class, NULL, 0, NULL, "sec_powerkey"); if (IS_ERR(sec_powerkey)) pr_err("Failed to create device(sec_powerkey)!\n"); ret = device_create_file(sec_powerkey, &dev_attr_sec_powerkey_pressed); if (ret) { pr_err("Failed to create device file in sysfs entries(%s)!\n", dev_attr_sec_powerkey_pressed.attr.name); } dev_set_drvdata(sec_powerkey, pon); return rc; }
static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi) { struct qpnp_vib *vib; struct resource *vib_resource; int rc; u8 val; u32 temp_val; vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL); if (!vib) return -ENOMEM; vib->spmi = spmi; vib->timeout = QPNP_VIB_DEFAULT_TIMEOUT; rc = of_property_read_u32(spmi->dev.of_node, "qcom,vib-timeout-ms", &temp_val); if (!rc) { vib->timeout = temp_val; } else if (rc != EINVAL) { dev_err(&spmi->dev, "Unable to read vib timeout\n"); return rc; } vib->vtg_level = QPNP_VIB_DEFAULT_VTG_LVL; rc = of_property_read_u32(spmi->dev.of_node, "qcom,vib-vtg-level-mV", &temp_val); if (!rc) { vib->vtg_level = temp_val; } else if (rc != -EINVAL) { dev_err(&spmi->dev, "Unable to read vtg level\n"); return rc; } vib->vtg_level /= 100; #ifdef CONFIG_VIBRATOR_PM8941_HAPTIC vib->vtg_haptic_level = QPNP_VIB_MAX_LEVEL; #endif 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; /* save the control registers values */ 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; 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; #ifdef CONFIG_VIBRATOR_PM8941_HAPTIC vib->timed_dev.set_vtLevel = qpnp_vib_set_level; vib->timed_dev.get_vtLevel = qpnp_vib_get_level; #endif dev_set_drvdata(&spmi->dev, vib); rc = timed_output_dev_register(&vib->timed_dev); if (rc < 0) return rc; vib_dev = vib; return rc; }
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_regulator_get_dt_config(struct spmi_device *spmi, struct qpnp_regulator_platform_data *pdata) { struct resource *res; struct device_node *node = spmi->dev.of_node; int rc = 0; pdata->init_data.constraints.input_uV = pdata->init_data.constraints.max_uV; res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!res) { dev_err(&spmi->dev, "%s: node is missing base address\n", __func__); return -EINVAL; } pdata->base_addr = res->start; pdata->ocp_irq = spmi_get_irq_byname(spmi, NULL, "ocp"); if (pdata->ocp_irq < 0) pdata->ocp_irq = 0; pdata->auto_mode_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->bypass_mode_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->ocp_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->pull_down_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->soft_start_enable = QPNP_REGULATOR_USE_HW_DEFAULT; pdata->boost_current_limit = QPNP_BOOST_CURRENT_LIMIT_HW_DEFAULT; pdata->pin_ctrl_enable = QPNP_REGULATOR_PIN_CTRL_ENABLE_HW_DEFAULT; pdata->pin_ctrl_hpm = QPNP_REGULATOR_PIN_CTRL_HPM_HW_DEFAULT; pdata->vs_soft_start_strength = QPNP_VS_SOFT_START_STR_HW_DEFAULT; pdata->hpm_enable = QPNP_REGULATOR_USE_HW_DEFAULT; of_property_read_u32(node, "qcom,auto-mode-enable", &pdata->auto_mode_enable); of_property_read_u32(node, "qcom,bypass-mode-enable", &pdata->bypass_mode_enable); of_property_read_u32(node, "qcom,ocp-enable", &pdata->ocp_enable); of_property_read_u32(node, "qcom,ocp-max-retries", &pdata->ocp_max_retries); of_property_read_u32(node, "qcom,ocp-retry-delay", &pdata->ocp_retry_delay_ms); of_property_read_u32(node, "qcom,pull-down-enable", &pdata->pull_down_enable); of_property_read_u32(node, "qcom,soft-start-enable", &pdata->soft_start_enable); of_property_read_u32(node, "qcom,boost-current-limit", &pdata->boost_current_limit); of_property_read_u32(node, "qcom,pin-ctrl-enable", &pdata->pin_ctrl_enable); of_property_read_u32(node, "qcom,pin-ctrl-hpm", &pdata->pin_ctrl_hpm); of_property_read_u32(node, "qcom,hpm-enable", &pdata->hpm_enable); of_property_read_u32(node, "qcom,vs-soft-start-strength", &pdata->vs_soft_start_strength); of_property_read_u32(node, "qcom,system-load", &pdata->system_load); of_property_read_u32(node, "qcom,enable-time", &pdata->enable_time); return rc; }
static int qpnp_flash_led_probe(struct spmi_device *spmi) { struct qpnp_flash_led *led; struct resource *flash_resource; struct device_node *node, *temp; int rc, i = 0, j, num_leds = 0; u32 val; node = spmi->dev.of_node; if (node == NULL) { dev_info(&spmi->dev, "No flash device defined\n"); return -ENODEV; } flash_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0); if (!flash_resource) { dev_err(&spmi->dev, "Unable to get flash LED base address\n"); return -EINVAL; } led = devm_kzalloc(&spmi->dev, sizeof(struct qpnp_flash_led), GFP_KERNEL); if (!led) { dev_err(&spmi->dev, "Unable to allocate memory for flash LED\n"); return -ENOMEM; } led->base = flash_resource->start; led->spmi_dev = spmi; led->pdata = devm_kzalloc(&spmi->dev, sizeof(struct flash_led_platform_data), GFP_KERNEL); if (!led->pdata) { dev_err(&spmi->dev, "Unable to allocate memory for platform data\n"); return -ENOMEM; } led->peripheral_type = (u8)qpnp_flash_led_get_peripheral_type(led); if (led->peripheral_type < 0) { dev_err(&spmi->dev, "Failed to get peripheral type\n"); return rc; } rc = qpnp_flash_led_parse_common_dt(led, node); if (rc) { dev_err(&spmi->dev, "Failed to get common config for flash LEDs\n"); return rc; } rc = qpnp_flash_led_init_settings(led); if (rc) { dev_err(&spmi->dev, "Failed to initialize flash LED\n"); return rc; } temp = NULL; while ((temp = of_get_next_child(node, temp))) num_leds++; if (!num_leds) return -ECHILD; led->flash_node = devm_kzalloc(&spmi->dev, (sizeof(struct flash_node_data) * num_leds), GFP_KERNEL); if (!led->flash_node) { dev_err(&spmi->dev, "Unable to allocate memory\n"); return -ENOMEM; } mutex_init(&led->flash_led_lock); for_each_child_of_node(node, temp) { led->flash_node[i].cdev.brightness_set = qpnp_flash_led_brightness_set; led->flash_node[i].cdev.brightness_get = qpnp_flash_led_brightness_get; led->flash_node[i].spmi_dev = spmi; INIT_WORK(&led->flash_node[i].work, qpnp_flash_led_work); rc = of_property_read_string(temp, "qcom,led-name", &led->flash_node[i].cdev.name); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Unable to read flash name\n"); return rc; } rc = of_property_read_string(temp, "qcom,default-led-trigger", &led->flash_node[i].cdev.default_trigger); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Unable to read trigger name\n"); return rc; } rc = of_property_read_u32(temp, "qcom,max-current", &val); if (!rc) { if (val < FLASH_LED_MIN_CURRENT_MA) val = FLASH_LED_MIN_CURRENT_MA; led->flash_node[i].max_current = (u16)val; led->flash_node[i].cdev.max_brightness = val; } else if (rc < 0) { dev_err(&led->spmi_dev->dev, "Unable to read max current\n"); return rc; } rc = led_classdev_register(&spmi->dev, &led->flash_node[i].cdev); if (rc) { dev_err(&spmi->dev, "Unable to register led\n"); goto error_led_register; } led->flash_node[i].cdev.dev->of_node = temp; rc = qpnp_flash_led_parse_each_led_dt(led, &led->flash_node[i]); if (rc) { dev_err(&spmi->dev, "Failed to parse config for each LED\n"); goto error_led_register; } for (j = 0; j < ARRAY_SIZE(qpnp_flash_led_attrs); j++) { rc = sysfs_create_file(&led->flash_node[i].cdev.dev->kobj, &qpnp_flash_led_attrs[j].attr); if (rc) goto error_led_register; } i++; }
static int __devinit qpnp_tm_probe(struct spmi_device *spmi) { struct device_node *node; struct resource *res; struct qpnp_tm_chip *chip; struct thermal_zone_device_ops *tz_ops; char *tm_name; u32 default_temperature; int rc = 0; u8 raw_type[2], type, subtype; #ifdef CONFIG_LGE_PM struct spmi_resource *spmi_resource; u8 batt_pres_rt_sts; #endif if (!spmi || !(&spmi->dev) || !spmi->dev.of_node) { dev_err(&spmi->dev, "%s: device tree node not found\n", __func__); return -EINVAL; } node = spmi->dev.of_node; chip = kzalloc(sizeof(struct qpnp_tm_chip), GFP_KERNEL); if (!chip) { dev_err(&spmi->dev, "%s: Can't allocate qpnp_tm_chip\n", __func__); return -ENOMEM; } dev_set_drvdata(&spmi->dev, chip); res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!res) { dev_err(&spmi->dev, "%s: node is missing base address\n", __func__); rc = -EINVAL; goto free_chip; } chip->base_addr = res->start; chip->spmi_dev = spmi; chip->irq = spmi_get_irq(spmi, NULL, 0); if (chip->irq < 0) { rc = chip->irq; dev_err(&spmi->dev, "%s: node is missing irq, rc=%d\n", __func__, rc); goto free_chip; } chip->tm_name = of_get_property(node, "label", NULL); if (chip->tm_name == NULL) { dev_err(&spmi->dev, "%s: node is missing label\n", __func__); rc = -EINVAL; goto free_chip; } tm_name = kstrdup(chip->tm_name, GFP_KERNEL); if (tm_name == NULL) { dev_err(&spmi->dev, "%s: could not allocate memory for label\n", __func__); rc = -ENOMEM; goto free_chip; } chip->tm_name = tm_name; INIT_DELAYED_WORK(&chip->irq_work, qpnp_tm_work); /* These bindings are optional, so it is okay if they are not found. */ chip->thresh = THRESH_MAX + 1; rc = of_property_read_u32(node, "qcom,threshold-set", &chip->thresh); if (!rc && (chip->thresh < THRESH_MIN || chip->thresh > THRESH_MAX)) dev_err(&spmi->dev, "%s: invalid qcom,threshold-set=%u specified\n", __func__, chip->thresh); chip->adc_type = QPNP_TM_ADC_NONE; rc = of_property_read_u32(node, "qcom,channel-num", &chip->adc_channel); if (!rc) { if (chip->adc_channel < 0 || chip->adc_channel >= ADC_MAX_NUM) { dev_err(&spmi->dev, "%s: invalid qcom,channel-num=%d specified\n", __func__, chip->adc_channel); } else { chip->adc_type = QPNP_TM_ADC_QPNP_ADC; chip->vadc_dev = qpnp_get_vadc(&spmi->dev, "temp_alarm"); if (IS_ERR(chip->vadc_dev)) { rc = PTR_ERR(chip->vadc_dev); if (rc != -EPROBE_DEFER) pr_err("vadc property missing\n"); goto err_cancel_work; } } } if (chip->adc_type == QPNP_TM_ADC_QPNP_ADC) tz_ops = &qpnp_thermal_zone_ops_qpnp_adc; else tz_ops = &qpnp_thermal_zone_ops_no_adc; chip->allow_software_override = of_property_read_bool(node, "qcom,allow-override"); default_temperature = DEFAULT_NO_ADC_TEMP; rc = of_property_read_u32(node, "qcom,default-temp", &default_temperature); chip->temperature = default_temperature; rc = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, raw_type, 2); if (rc) { dev_err(&spmi->dev, "%s: could not read type register, rc=%d\n", __func__, rc); goto err_cancel_work; } type = raw_type[0]; subtype = raw_type[1]; if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) { dev_err(&spmi->dev, "%s: invalid type=%02X or subtype=%02X register value\n", __func__, type, subtype); rc = -ENODEV; goto err_cancel_work; } rc = qpnp_tm_init_reg(chip); if (rc) { dev_err(&spmi->dev, "%s: qpnp_tm_init_reg() failed, rc=%d\n", __func__, rc); goto err_cancel_work; } if (chip->adc_type == QPNP_TM_ADC_NONE) { rc = qpnp_tm_init_temp_no_adc(chip); if (rc) { dev_err(&spmi->dev, "%s: qpnp_tm_init_temp_no_adc() failed, rc=%d\n", __func__, rc); goto err_cancel_work; } } /* Start in HW control; switch to SW control when user changes mode. */ chip->mode = THERMAL_DEVICE_DISABLED; rc = qpnp_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED); if (rc) { dev_err(&spmi->dev, "%s: qpnp_tm_shutdown_override() failed, rc=%d\n", __func__, rc); goto err_cancel_work; } chip->tz_dev = thermal_zone_device_register(tm_name, TRIP_NUM, chip, tz_ops, 0, 0, 0, 0); if (chip->tz_dev == NULL) { dev_err(&spmi->dev, "%s: thermal_zone_device_register() failed.\n", __func__); rc = -ENODEV; goto err_cancel_work; } rc = request_irq(chip->irq, qpnp_tm_isr, IRQF_TRIGGER_RISING, tm_name, chip); if (rc < 0) { dev_err(&spmi->dev, "%s: request_irq(%d) failed: %d\n", __func__, chip->irq, rc); goto err_free_tz; } #ifdef CONFIG_LGE_PM spmi_for_each_container_dev(spmi_resource, spmi) { if (!spmi_resource) { pr_err("qpnp temp alarm : spmi resource absent\n"); goto fail_bat_if; } res = spmi_get_resource(spmi, spmi_resource, IORESOURCE_MEM, 0); if (!(res && res->start)) { pr_err("node %s IO resource absent!\n", spmi->dev.of_node->full_name); goto fail_bat_if; } rc = qpnp_register_read(chip, &subtype, res->start + REG_OFFSET_PERP_SUBTYPE, 1); if (rc) { pr_err("Peripheral subtype read failed rc=%d\n", rc); goto fail_bat_if; } switch (subtype) { case SMBB_BAT_IF_SUBTYPE: pr_err("qpnp bat_if block enable for batt insert remove irq.\n"); chip->bat_if_base = res->start; chip->batt_present_irq = spmi_get_irq_byname(chip->spmi_dev, spmi_resource, "batt-pres"); if (chip->batt_present_irq < 0) { pr_err("Unable to get batt_present_irq\n"); goto fail_bat_if; } rc = devm_request_irq(&(chip->spmi_dev->dev), chip->batt_present_irq, qpnp_batif_batt_inserted_removed_irq_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "batt_remove_insert", chip); if (rc < 0) { pr_err("Can't request %d batt irq for insert, remove : %d\n", chip->batt_present_irq, rc); goto fail_bat_if; } rc = qpnp_register_masked_write(chip, INT_EN_SET(chip->bat_if_base), BATT_PRES_EN_BIT, BATT_PRES_EN_BIT, 1); if (rc) { pr_err("failed to enable BAT_IF_INT_EN_SET rc=%d\n", rc); goto fail_bat_if; } /* smb349 charger battery present W/A */ rc = qpnp_register_read(chip, &batt_pres_rt_sts, INT_RT_STS(chip->bat_if_base), 1); if (rc) { pr_err("spmi read failed: addr=%03X, rc=%d\n", INT_RT_STS(chip->bat_if_base), rc); pr_err("assume that battery is present\n"); /* battery present */ pm_batt_rt_sts = 1; } else { pm_batt_rt_sts = (int)(batt_pres_rt_sts & BATT_IF_PRES_RT_STATUS); pr_err("%s : init PMIC battery RTS = %d\n", __func__, pm_batt_rt_sts); } enable_irq_wake(chip->batt_present_irq); break; default: break; } } INIT_WORK(&chip->batt_insert_remove_worker, batt_insert_remove_work); INIT_DELAYED_WORK(&chip->batt_insert_remove_worker_second, batt_insert_remove_work_second); wake_lock_init(&chip->battgone_wake_lock, WAKE_LOCK_SUSPEND, "batt removed"); #endif return 0; err_free_tz: thermal_zone_device_unregister(chip->tz_dev); err_cancel_work: cancel_delayed_work_sync(&chip->irq_work); kfree(chip->tm_name); free_chip: dev_set_drvdata(&spmi->dev, NULL); kfree(chip); return rc; #ifdef CONFIG_LGE_PM fail_bat_if: pr_err("Cannot enable qpnp bat_if block.\n"); return 0; #endif }
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; }
static int __devinit spm_regulator_probe(struct spmi_device *spmi) { struct device_node *node = spmi->dev.of_node; struct regulator_init_data *init_data; struct spm_vreg *vreg; struct resource *res; int rc; if (!node) { dev_err(&spmi->dev, "%s: device node missing\n", __func__); return -ENODEV; } vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL); if (!vreg) { pr_err("allocation failed.\n"); return -ENOMEM; } vreg->spmi_dev = spmi; res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!res) { dev_err(&spmi->dev, "%s: node is missing base address\n", __func__); return -EINVAL; } vreg->spmi_base_addr = res->start; rc = qpnp_fts2_check_type(vreg); if (rc) return rc; /* */ rc = qpnp_fts2_init_range(vreg); if (rc) return rc; rc = qpnp_fts2_init_voltage(vreg); if (rc) return rc; rc = qpnp_fts2_init_mode(vreg); if (rc) return rc; rc = qpnp_fts2_init_step_rate(vreg); if (rc) return rc; init_data = of_get_regulator_init_data(&spmi->dev, node); if (!init_data) { dev_err(&spmi->dev, "%s: unable to allocate memory\n", __func__); return -ENOMEM; } init_data->constraints.input_uV = init_data->constraints.max_uV; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE; if (!init_data->constraints.name) { dev_err(&spmi->dev, "%s: node is missing regulator name\n", __func__); return -EINVAL; } vreg->rdesc.name = init_data->constraints.name; vreg->rdesc.type = REGULATOR_VOLTAGE; vreg->rdesc.owner = THIS_MODULE; vreg->rdesc.ops = &spm_regulator_ops; vreg->rdesc.n_voltages = (vreg->range->max_uV - vreg->range->set_point_min_uV) / vreg->range->step_uV + 1; vreg->rdev = regulator_register(&vreg->rdesc, &spmi->dev, init_data, vreg, node); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); dev_err(&spmi->dev, "%s: regulator_register failed, rc=%d\n", __func__, rc); return rc; } dev_set_drvdata(&spmi->dev, vreg); pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n", vreg->rdesc.name, vreg->range == &fts2_range0 ? "LV" : "MV", vreg->uV, vreg->init_mode & QPNP_FTS2_MODE_PWM ? "PWM" : (vreg->init_mode & QPNP_FTS2_MODE_AUTO ? "AUTO" : "PFM"), vreg->step_rate); return rc; }
static int __devinit pm8941_flash_probe(struct spmi_device *spmi) { struct pm8941_flash_data *data; struct resource *flash_resource; struct device_node *node; int rc; const char *flash_label; node = spmi->dev.of_node; if (node == NULL) return -ENODEV; data = kzalloc(sizeof(struct pm8941_flash_data), GFP_KERNEL); if (!data) { dev_err(&spmi->dev, "Unable to allocate memory\n"); return -ENOMEM; } data->cdev.minor = MISC_DYNAMIC_MINOR; data->cdev.name = "pm8941-flash"; data->cdev.parent = &spmi->dev; data->spmi_dev = spmi; flash_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!flash_resource) { dev_err(&spmi->dev, "Unable to get flash base address\n"); rc = -ENXIO; goto fail_id_check; } data->base = flash_resource->start; rc = of_property_read_string(node, "label", &flash_label); if (rc < 0) { dev_err(&spmi->dev, "Failure reading label, rc = %d\n", rc); goto fail_id_check; } if (strncmp(flash_label, "flash", sizeof("flash")) != 0) { dev_err(&spmi->dev, "No matching label\n"); rc = -EINVAL; goto fail_id_check; } rc = pm8941_get_config_flash(data, node); if (rc < 0) { dev_err(&spmi->dev, "Unable to read config data\n"); goto fail_id_check; } rc = pm8941_power_init(data); if (rc) goto fail_id_check; mutex_init(&data->lock); data->scheduled = false; data->boost_for_torch.requested = false; data->boost_for_flash.requested = false; rc = pm8941_flash_initialize(data); if (rc < 0) goto fail_id_check; rc = pm8941_attributes_init(data); if (rc) goto remove_attributes; dev_set_drvdata(&spmi->dev, data); if (misc_register(&data->cdev)) { dev_err(&spmi->dev, "misc_register failed.\n"); goto remove_attributes; } return 0; remove_attributes: pm8941_attributes_remove(data); fail_id_check: pm8941_regulator_exit(&data->spmi_dev->dev, &data->boost_for_flash); pm8941_regulator_exit(&data->spmi_dev->dev, &data->boost_for_torch); kfree(data); return rc; }
static int __devinit qpnp_vibrator_probe(struct spmi_device *spmi) { struct qpnp_vib *vib; const __be32 *temp_dt; struct resource *vib_resource; int rc = -ENOMEM; u8 val; vib = devm_kzalloc(&spmi->dev, sizeof(*vib), GFP_KERNEL); if (!vib) goto gen_err; 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 /= QPNP_VIB_UV_PER_MV; vib_resource = spmi_get_resource(spmi, 0, IORESOURCE_MEM, 0); if (!vib_resource) { dev_err(&spmi->dev, "Unable to get vibrator base address\n"); rc = -EINVAL; goto gen_err; } vib->base = vib_resource->start; /* save the control registers values */ rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_VTG_CTL(vib->base)); if (rc < 0) goto gen_err; vib->reg_vtg_ctl = val; rc = qpnp_vib_read_u8(vib, &val, QPNP_VIB_EN_CTL(vib->base)); if (rc < 0) goto gen_err; 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; rc = timed_output_dev_register(&vib->timed_dev); if (rc < 0) goto gen_err; vib->sysfs_dev.init_name = "qpnp_vib"; rc = device_register(&vib->sysfs_dev); if (rc < 0) { dev_err(&spmi->dev, "%s: device_register failed %d\n", __func__, rc); goto error_dev_register; } rc = device_create_file(&vib->sysfs_dev, &qpnp_vib_attr); if (rc < 0) { dev_err(&spmi->dev, "%s: device_create_file failed %d\n", __func__, rc); goto error_device_create_file; } dev_set_drvdata(&spmi->dev, vib); vib_dev = vib; return rc; error_device_create_file: device_unregister(&vib->sysfs_dev); error_dev_register: timed_output_dev_unregister(&vib->timed_dev); gen_err: return rc; }
static int __devinit qpnp_tm_probe(struct spmi_device *spmi) { struct device_node *node; struct resource *res; struct qpnp_tm_chip *chip; struct thermal_zone_device_ops *tz_ops; char *tm_name; u32 default_temperature; int rc = 0; u8 raw_type[2], type, subtype; if (!spmi || !(&spmi->dev) || !spmi->dev.of_node) { dev_err(&spmi->dev, "%s: device tree node not found\n", __func__); return -EINVAL; } node = spmi->dev.of_node; chip = kzalloc(sizeof(struct qpnp_tm_chip), GFP_KERNEL); if (!chip) { dev_err(&spmi->dev, "%s: Can't allocate qpnp_tm_chip\n", __func__); return -ENOMEM; } dev_set_drvdata(&spmi->dev, chip); res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!res) { dev_err(&spmi->dev, "%s: node is missing base address\n", __func__); rc = -EINVAL; goto free_chip; } chip->base_addr = res->start; chip->spmi_dev = spmi; chip->irq = spmi_get_irq(spmi, NULL, 0); if (chip->irq < 0) { rc = chip->irq; dev_err(&spmi->dev, "%s: node is missing irq, rc=%d\n", __func__, rc); goto free_chip; } chip->tm_name = of_get_property(node, "label", NULL); if (chip->tm_name == NULL) { dev_err(&spmi->dev, "%s: node is missing label\n", __func__); rc = -EINVAL; goto free_chip; } tm_name = kstrdup(chip->tm_name, GFP_KERNEL); if (tm_name == NULL) { dev_err(&spmi->dev, "%s: could not allocate memory for label\n", __func__); rc = -ENOMEM; goto free_chip; } chip->tm_name = tm_name; INIT_DELAYED_WORK(&chip->irq_work, qpnp_tm_work); /* These bindings are optional, so it is okay if they are not found. */ chip->thresh = THRESH_MAX + 1; rc = of_property_read_u32(node, "qcom,threshold-set", &chip->thresh); if (!rc && (chip->thresh < THRESH_MIN || chip->thresh > THRESH_MAX)) dev_err(&spmi->dev, "%s: invalid qcom,threshold-set=%u specified\n", __func__, chip->thresh); chip->adc_type = QPNP_TM_ADC_NONE; rc = of_property_read_u32(node, "qcom,channel-num", &chip->adc_channel); if (!rc) { if (chip->adc_channel < 0 || chip->adc_channel >= ADC_MAX_NUM) { dev_err(&spmi->dev, "%s: invalid qcom,channel-num=%d specified\n", __func__, chip->adc_channel); } else { chip->adc_type = QPNP_TM_ADC_QPNP_ADC; rc = qpnp_vadc_is_ready(); if (rc) { /* Probe retry, do not print an error message */ goto err_cancel_work; } } } if (chip->adc_type == QPNP_TM_ADC_QPNP_ADC) tz_ops = &qpnp_thermal_zone_ops_qpnp_adc; else tz_ops = &qpnp_thermal_zone_ops_no_adc; chip->allow_software_override = of_property_read_bool(node, "qcom,allow-override"); default_temperature = DEFAULT_NO_ADC_TEMP; rc = of_property_read_u32(node, "qcom,default-temp", &default_temperature); chip->temperature = default_temperature; rc = qpnp_tm_read(chip, QPNP_TM_REG_TYPE, raw_type, 2); if (rc) { dev_err(&spmi->dev, "%s: could not read type register, rc=%d\n", __func__, rc); goto err_cancel_work; } type = raw_type[0]; subtype = raw_type[1]; if (type != QPNP_TM_TYPE || subtype != QPNP_TM_SUBTYPE) { dev_err(&spmi->dev, "%s: invalid type=%02X or subtype=%02X register value\n", __func__, type, subtype); rc = -ENODEV; goto err_cancel_work; } rc = qpnp_tm_init_reg(chip); if (rc) { dev_err(&spmi->dev, "%s: qpnp_tm_init_reg() failed, rc=%d\n", __func__, rc); goto err_cancel_work; } if (chip->adc_type == QPNP_TM_ADC_NONE) { rc = qpnp_tm_init_temp_no_adc(chip); if (rc) { dev_err(&spmi->dev, "%s: qpnp_tm_init_temp_no_adc() failed, rc=%d\n", __func__, rc); goto err_cancel_work; } } /* Start in HW control; switch to SW control when user changes mode. */ chip->mode = THERMAL_DEVICE_DISABLED; rc = qpnp_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED); if (rc) { dev_err(&spmi->dev, "%s: qpnp_tm_shutdown_override() failed, rc=%d\n", __func__, rc); goto err_cancel_work; } chip->tz_dev = thermal_zone_device_register(tm_name, TRIP_NUM, chip, tz_ops, 0, 0, 0, 0); if (chip->tz_dev == NULL) { dev_err(&spmi->dev, "%s: thermal_zone_device_register() failed.\n", __func__); rc = -ENODEV; goto err_cancel_work; } rc = request_irq(chip->irq, qpnp_tm_isr, IRQF_TRIGGER_RISING, tm_name, chip); if (rc < 0) { dev_err(&spmi->dev, "%s: request_irq(%d) failed: %d\n", __func__, chip->irq, rc); goto err_free_tz; } return 0; err_free_tz: thermal_zone_device_unregister(chip->tz_dev); err_cancel_work: cancel_delayed_work_sync(&chip->irq_work); kfree(chip->tm_name); free_chip: dev_set_drvdata(&spmi->dev, NULL); kfree(chip); return rc; }
static int __devinit qpnp_leds_probe(struct spmi_device *spmi) { struct qpnp_led_data *led, *led_array; struct resource *led_resource; struct device_node *node, *temp; int rc, i, num_leds = 0, parsed_leds = 0; const char *led_label; node = spmi->dev.of_node; if (node == NULL) return -ENODEV; temp = NULL; while ((temp = of_get_next_child(node, temp))) num_leds++; if (!num_leds) return -ECHILD; led_array = devm_kzalloc(&spmi->dev, (sizeof(struct qpnp_led_data) * num_leds), GFP_KERNEL); if (!led_array) { dev_err(&spmi->dev, "Unable to allocate memory\n"); return -ENOMEM; } for_each_child_of_node(node, temp) { led = &led_array[parsed_leds]; led->num_leds = num_leds; led->spmi_dev = spmi; led_resource = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!led_resource) { dev_err(&spmi->dev, "Unable to get LED base address\n"); rc = -ENXIO; goto fail_id_check; } led->base = led_resource->start; rc = of_property_read_string(temp, "label", &led_label); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Failure reading label, rc = %d\n", rc); goto fail_id_check; } rc = of_property_read_string(temp, "linux,name", &led->cdev.name); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Failure reading led name, rc = %d\n", rc); goto fail_id_check; } rc = of_property_read_u32(temp, "qcom,max-current", &led->max_current); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Failure reading max_current, rc = %d\n", rc); goto fail_id_check; } rc = of_property_read_u32(temp, "qcom,id", &led->id); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Failure reading led id, rc = %d\n", rc); goto fail_id_check; } rc = qpnp_get_common_configs(led, temp); if (rc) { dev_err(&led->spmi_dev->dev, "Failure reading common led configuration," \ " rc = %d\n", rc); goto fail_id_check; } led->cdev.brightness_set = qpnp_led_set; led->cdev.brightness_get = qpnp_led_get; if (strncmp(led_label, "wled", sizeof("wled")) == 0) { rc = qpnp_get_config_wled(led, temp); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Unable to read wled config data\n"); goto fail_id_check; } } else if (strncmp(led_label, "flash", sizeof("flash")) == 0) { rc = qpnp_get_config_flash(led, temp); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Unable to read flash config data\n"); goto fail_id_check; } } else if (strncmp(led_label, "rgb", sizeof("rgb")) == 0) { rc = qpnp_get_config_rgb(led, temp); if (rc < 0) { dev_err(&led->spmi_dev->dev, "Unable to read rgb config data\n"); goto fail_id_check; } } else { dev_err(&led->spmi_dev->dev, "No LED matching label\n"); rc = -EINVAL; goto fail_id_check; } spin_lock_init(&led->lock); rc = qpnp_led_initialize(led); if (rc < 0) goto fail_id_check; rc = qpnp_led_set_max_brightness(led); if (rc < 0) goto fail_id_check; rc = led_classdev_register(&spmi->dev, &led->cdev); if (rc) { dev_err(&spmi->dev, "unable to register led %d,rc=%d\n", led->id, rc); goto fail_id_check; } /* configure default state */ if (led->default_on) { led->cdev.brightness = led->cdev.max_brightness; if (led->turn_off_delay_ms > 0) qpnp_led_turn_off(led); } else led->cdev.brightness = LED_OFF; qpnp_led_set(&led->cdev, led->cdev.brightness); parsed_leds++; }
static int spm_regulator_probe(struct spmi_device *spmi) { struct regulator_config reg_config = {}; struct device_node *node = spmi->dev.of_node; struct regulator_init_data *init_data; struct spm_vreg *vreg; struct resource *res; bool bypass_spm; int rc; if (!node) { dev_err(&spmi->dev, "%s: device node missing\n", __func__); return -ENODEV; } bypass_spm = of_property_read_bool(node, "qcom,bypass-spm"); if (!bypass_spm) { rc = msm_spm_probe_done(); if (rc) { if (rc != -EPROBE_DEFER) dev_err(&spmi->dev, "%s: spm unavailable, rc=%d\n", __func__, rc); return rc; } } vreg = devm_kzalloc(&spmi->dev, sizeof(*vreg), GFP_KERNEL); if (!vreg) { pr_err("allocation failed.\n"); return -ENOMEM; } vreg->spmi_dev = spmi; vreg->bypass_spm = bypass_spm; res = spmi_get_resource(spmi, NULL, IORESOURCE_MEM, 0); if (!res) { dev_err(&spmi->dev, "%s: node is missing base address\n", __func__); return -EINVAL; } vreg->spmi_base_addr = res->start; rc = qpnp_smps_check_type(vreg); if (rc) return rc; /* Specify CPU 0 as default in order to handle shared regulator case. */ vreg->cpu_num = 0; of_property_read_u32(vreg->spmi_dev->dev.of_node, "qcom,cpu-num", &vreg->cpu_num); /* * The regulator must be initialized to range 0 or range 1 during * PMIC power on sequence. Once it is set, it cannot be changed * dynamically. */ if (vreg->regulator_type == QPNP_TYPE_FTS2) rc = qpnp_fts_init_range(vreg, &fts2_range0, &fts2_range1); else if (vreg->regulator_type == QPNP_TYPE_FTS2p5) rc = qpnp_fts_init_range(vreg, &fts2p5_range0, &fts2p5_range1); else if (vreg->regulator_type == QPNP_TYPE_ULT_HF) rc = qpnp_ult_hf_init_range(vreg); if (rc) return rc; rc = qpnp_smps_init_voltage(vreg); if (rc) return rc; rc = qpnp_smps_init_mode(vreg); if (rc) return rc; rc = qpnp_smps_init_step_rate(vreg); if (rc) return rc; init_data = of_get_regulator_init_data(&spmi->dev, node); if (!init_data) { dev_err(&spmi->dev, "%s: unable to allocate memory\n", __func__); return -ENOMEM; } init_data->constraints.input_uV = init_data->constraints.max_uV; init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_STATUS | REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE; init_data->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE; if (!init_data->constraints.name) { dev_err(&spmi->dev, "%s: node is missing regulator name\n", __func__); return -EINVAL; } vreg->rdesc.name = init_data->constraints.name; vreg->rdesc.type = REGULATOR_VOLTAGE; vreg->rdesc.owner = THIS_MODULE; vreg->rdesc.ops = &spm_regulator_ops; vreg->rdesc.n_voltages = (vreg->range->max_uV - vreg->range->set_point_min_uV) / vreg->range->step_uV + 1; reg_config.dev = &spmi->dev; reg_config.init_data = init_data; reg_config.driver_data = vreg; reg_config.of_node = node; vreg->rdev = regulator_register(&vreg->rdesc, ®_config); if (IS_ERR(vreg->rdev)) { rc = PTR_ERR(vreg->rdev); dev_err(&spmi->dev, "%s: regulator_register failed, rc=%d\n", __func__, rc); return rc; } dev_set_drvdata(&spmi->dev, vreg); pr_info("name=%s, range=%s, voltage=%d uV, mode=%s, step rate=%d uV/us\n", vreg->rdesc.name, spm_regulator_using_range0(vreg) ? "LV" : "MV", vreg->uV, vreg->init_mode & QPNP_SMPS_MODE_PWM ? "PWM" : (vreg->init_mode & QPNP_FTS2_MODE_AUTO ? "AUTO" : "PFM"), vreg->step_rate); return rc; }