示例#1
0
static int __devinit pm8921_probe(struct platform_device *pdev)
{
	const struct pm8921_platform_data *pdata = pdev->dev.platform_data;
	const char *revision_name = "unknown";
	struct pm8921 *pmic;
#ifdef CONFIG_MACH_ACER_A9
	struct kobject *dev_info_pmic_kobj;
#else
	enum pm8xxx_version version;
	int revision;
#endif
	int rc;
	u8 val;

	if (!pdata) {
		pr_err("missing platform data\n");
		return -EINVAL;
	}

	pmic = kzalloc(sizeof(struct pm8921), GFP_KERNEL);
	if (!pmic) {
		pr_err("Cannot alloc pm8921 struct\n");
		return -ENOMEM;
	}

	/* Read PMIC chip revision */
	rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV, &val, sizeof(val));
	if (rc) {
		pr_err("Failed to read hw rev reg %d:rc=%d\n", REG_HWREV, rc);
		goto err_read_rev;
	}
	pr_info("PMIC revision 1: %02X\n", val);
	pmic->rev_registers = val;

	/* Read PMIC chip revision 2 */
	rc = msm_ssbi_read(pdev->dev.parent, REG_HWREV_2, &val, sizeof(val));
	if (rc) {
		pr_err("Failed to read hw rev 2 reg %d:rc=%d\n",
			REG_HWREV_2, rc);
		goto err_read_rev;
	}
	pr_info("PMIC revision 2: %02X\n", val);
	pmic->rev_registers |= val << BITS_PER_BYTE;

	pmic->dev = &pdev->dev;
	pm8921_drvdata.pm_chip_data = pmic;
	platform_set_drvdata(pdev, &pm8921_drvdata);

	/* Print out human readable version and revision names. */
	version = pm8xxx_get_version(pmic->dev);
	revision = pm8xxx_get_revision(pmic->dev);
	if (version == PM8XXX_VERSION_8921) {
		if (revision >= 0 && revision < ARRAY_SIZE(pm8921_rev_names))
			revision_name = pm8921_rev_names[revision];
		pr_info("PMIC version: PM8921 rev %s\n", revision_name);
	} else if (version == PM8XXX_VERSION_8922) {
		if (revision >= 0 && revision < ARRAY_SIZE(pm8922_rev_names))
			revision_name = pm8922_rev_names[revision];
		pr_info("PMIC version: PM8922 rev %s\n", revision_name);
	} else if (version == PM8XXX_VERSION_8917) {
		if (revision >= 0 && revision < ARRAY_SIZE(pm8917_rev_names))
			revision_name = pm8917_rev_names[revision];
		pr_info("PMIC version: PM8917 rev %s\n", revision_name);
	} else {
		WARN_ON(version != PM8XXX_VERSION_8921
			&& version != PM8XXX_VERSION_8922
			&& version != PM8XXX_VERSION_8917);
	}

#ifdef CONFIG_MACH_ACER_A9
	dev_info_pmic_kobj = kobject_create_and_add("dev-info_pmic", NULL);
	if (dev_info_pmic_kobj == NULL) {
		pr_err("Failed to create dev-info_pmic kobject\n");
	}

	rc = sysfs_create_group(dev_info_pmic_kobj, &pmic_attr_group);
	if(rc) {
		pr_err("Failed to create dev-info_pmic sysfs group\n");
	}
#endif

	/* Log human readable restart reason */
	rc = msm_ssbi_read(pdev->dev.parent, REG_PM8921_PON_CNTRL_3, &val, 1);
	if (rc) {
		pr_err("Cannot read restart reason rc=%d\n", rc);
		goto err_read_rev;
	}
	val &= PM8921_RESTART_REASON_MASK;
	pr_info("PMIC Restart Reason: %s\n", pm8921_restart_reason[val]);

	rc = pm8921_add_subdevices(pdata, pmic);
	if (rc) {
		pr_err("Cannot add subdevices rc=%d\n", rc);
		goto err;
	}

	/* gpio might not work if no irq device is found */
	WARN_ON(pmic->irq_chip == NULL);

	return 0;

err:
	mfd_remove_devices(pmic->dev);
	platform_set_drvdata(pdev, NULL);
	kfree(pmic->mfd_regulators);
	kfree(pmic->regulator_cdata);
err_read_rev:
	kfree(pmic);
	return rc;
}
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]);
}

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_attributes[] = {
	&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
};

static const struct attribute_group twl4030_madc_group = {
	.attrs = twl4030_madc_attributes,
};

static int __devinit twl4030_madc_hwmon_probe(struct platform_device *pdev)
{
	int ret;
	struct device *hwmon;

	ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group);
	if (ret)
		goto err_sysfs;
	hwmon = hwmon_device_register(&pdev->dev);
	if (IS_ERR(hwmon)) {
		dev_err(&pdev->dev, "hwmon_device_register failed.\n");
		ret = PTR_ERR(hwmon);
		goto err_reg;
	}

	return 0;

err_reg:
	sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
err_sysfs:

	return ret;
}
示例#3
0
/* Add/Remove cpu_topology interface for CPU device */
static int __cpuinit topology_add_dev(struct sys_device * sys_dev)
{
	sysfs_create_group(&sys_dev->kobj, &topology_attr_group);
	return 0;
}
示例#4
0
static inline int s3c_hwmon_add_raw(struct device *dev)
{
	return sysfs_create_group(&dev->kobj, &s3c_hwmon_attrgroup);
}
static int __devinit ami306_probe(struct i2c_client *client, 
		const struct i2c_device_id * devid)
{
	int err = 0;
	struct ami306_i2c_data *data;
	struct ecom_platform_data* ecom_pdata;

	if (AMI306_DEBUG_FUNC_TRACE & ami306_debug_mask)
		AMID("motion start....!\n");

	if(!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		AMIE("adapter can NOT support I2C_FUNC_I2C.\n");
		return -ENODEV;
	}

	if (!(data = kmalloc(sizeof(struct ami306_i2c_data), GFP_KERNEL))) {
		err = -ENOMEM;
		goto exit;
	}
	memset(data, 0, sizeof(struct ami306_i2c_data));

	data->client = client;
	i2c_set_clientdata(client, data);
	ami306_i2c_client = client;

	ecom_pdata = ami306_i2c_client->dev.platform_data;
	ecom_pdata->power(1);

#if defined(CONFIG_HAS_EARLYSUSPEND)
	ami306_sensor_early_suspend.suspend = ami306_early_suspend;
	ami306_sensor_early_suspend.resume = ami306_late_resume;
	register_early_suspend(&ami306_sensor_early_suspend);

	atomic_set(&ami306_report_enabled, 1);
#endif
	err=Identify_AMI_Chipset();
	if (err != 0) {  //get ami306_data.chipset
		printk(KERN_INFO "Failed to identify AMI_Chipset!\n");	
		goto exit_kfree;
	}

	AMI306_Chipset_Init(AMI306_FORCE_MODE, ami306_data.chipset); // default is Force State	
	dev_info(&client->dev, "%s operating mode\n", ami306_data.mode? "force" : "normal");

	printk(KERN_INFO "Register input device!\n");	
	err = ami306_input_init(data);
	if(err)
		goto exit_kfree;

	//register misc device:ami306	       
	err = misc_register(&ami306_device);
	if (err) {
		AMIE("ami306_device register failed\n");
		goto exit_misc_ami306_device_register_failed;
	}
	//register misc device:ami306daemon	
	err = misc_register(&ami306daemon_device);
	if (err) {
		AMIE("ami306daemon_device register failed\n");
		goto exit_misc_ami306daemon_device_register_failed;
	}
	//register misc device:ami306hal
	err = misc_register(&ami306hal_device);
	if (err) {
		AMIE("ami306hal_device register failed\n");
		goto exit_misc_ami306hal_device_register_failed;
	}

	/* Register sysfs hooks */
	err = sysfs_create_group(&client->dev.kobj, &ami306_attribute_group);
	if (err) {
		AMIE("ami306 sysfs register failed\n");
		goto exit_sysfs_create_group_failed;
	}
	printk(KERN_INFO "[jaekyung83.lee] ami306 probe");
	return 0;

exit_sysfs_create_group_failed:	
	sysfs_remove_group(&client->dev.kobj, &ami306_attribute_group);
exit_misc_ami306hal_device_register_failed:
	misc_deregister(&ami306daemon_device);
exit_misc_ami306daemon_device_register_failed:
	misc_deregister(&ami306_device);
exit_misc_ami306_device_register_failed:
	input_unregister_device(data->input_dev);
	input_free_device(data->input_dev);
exit_kfree:
	kfree(data);
exit:
	return err;
}
示例#6
0
static int cpufreq_stats_create_table(struct cpufreq_policy *policy,
                                      struct cpufreq_frequency_table *table)
{
    unsigned int i, j, count = 0, ret = 0;
    struct cpufreq_stats *stat;
    struct cpufreq_policy *data;
    unsigned int alloc_size;
    unsigned int cpu = policy->cpu;
    if (per_cpu(cpufreq_stats_table, cpu))
        return -EBUSY;
    stat = kzalloc(sizeof(struct cpufreq_stats), GFP_KERNEL);
    if ((stat) == NULL)
        return -ENOMEM;

    data = cpufreq_cpu_get(cpu);
    if (data == NULL) {
        ret = -EINVAL;
        goto error_get_fail;
    }

    ret = sysfs_create_group(&data->kobj, &stats_attr_group);
    if (ret)
        goto error_out;

    stat->cpu = cpu;
    per_cpu(cpufreq_stats_table, cpu) = stat;

    for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
        unsigned int freq = table[i].frequency;
        if (freq == CPUFREQ_ENTRY_INVALID)
            continue;
        count++;
    }

    alloc_size = count * sizeof(int) + count * sizeof(cputime64_t);

#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
    alloc_size += count * count * sizeof(int);
#endif
    stat->max_state = count;
    stat->time_in_state = kzalloc(alloc_size, GFP_KERNEL);
    if (!stat->time_in_state) {
        ret = -ENOMEM;
        goto error_out;
    }
    stat->freq_table = (unsigned int *)(stat->time_in_state + count);

#ifdef CONFIG_CPU_FREQ_STAT_DETAILS
    stat->trans_table = stat->freq_table + count;
#endif
    j = 0;
    for (i = 0; table[i].frequency != CPUFREQ_TABLE_END; i++) {
        unsigned int freq = table[i].frequency;
        if (freq == CPUFREQ_ENTRY_INVALID)
            continue;
        if (freq_table_get_index(stat, freq) == -1)
            stat->freq_table[j++] = freq;
    }
    stat->state_num = j;
    spin_lock(&cpufreq_stats_lock);
    stat->last_time = get_jiffies_64();
    stat->last_index = freq_table_get_index(stat, policy->cur);
    spin_unlock(&cpufreq_stats_lock);
    cpufreq_cpu_put(data);
    return 0;
error_out:
    cpufreq_cpu_put(data);
error_get_fail:
    kfree(stat);
    per_cpu(cpufreq_stats_table, cpu) = NULL;
    return ret;
}
static int fpc1020_probe(struct spi_device *spi)
{
	struct device *dev = &spi->dev;
	struct device_node *np = dev->of_node;
	struct fpc1020_data *fpc1020;
	size_t i;
	int irqf = 0;
	int rc = 0;
	u32 val;
	fpc1020 = devm_kzalloc(dev, sizeof(*fpc1020), GFP_KERNEL);
	if (!fpc1020) {
		dev_err(dev, "failed to allocate memory\n");
		rc = -ENOMEM;
		goto exit;
	}

	fpc1020->dev = dev;
	dev_set_drvdata(dev, fpc1020);
	fpc1020->spi = spi;

	if (!np) {
		dev_err(dev, "of node found\n");
		rc = -EINVAL;
		goto exit;
	}

	rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_irq",
			&fpc1020->irq_gpio);
	if (rc)
		goto exit;

	rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_cs0",
			&fpc1020->cs0_gpio);
	if (rc)
		goto exit;

	rc = fpc1020_request_named_gpio(fpc1020, "fpc,gpio_rst",
			&fpc1020->rst_gpio);
	if (rc)
		goto exit;

	fpc1020->iface_clk = clk_get(dev, "iface_clk");
	if (IS_ERR(fpc1020->iface_clk)) {
		dev_err(dev, "%s: failed to get iface_clk\n", __func__);
		rc = -EINVAL;
		goto exit;
	}

	fpc1020->core_clk = clk_get(dev, "core_clk");
	if (IS_ERR(fpc1020->core_clk)) {
		dev_err(dev, "%s: failed to get core_clk\n", __func__);
		rc = -EINVAL;
		goto exit;
	}

	rc = of_property_read_u32(np, "qcom,spi-qup-id", &val);
	if (rc < 0) {
		dev_err(dev, "qcom,spi-qup-id not found\n");
		goto exit;
	}

	fpc1020->qup_id = val;
	dev_dbg(dev, "qcom,spi-qup-id %d\n", fpc1020->qup_id);

	fpc1020->fingerprint_pinctrl = devm_pinctrl_get(dev);
	if (IS_ERR(fpc1020->fingerprint_pinctrl)) {
		if (PTR_ERR(fpc1020->fingerprint_pinctrl) == -EPROBE_DEFER) {
			dev_info(dev, "pinctrl not ready\n");
			rc = -EPROBE_DEFER;
			goto exit;
		}
		dev_err(dev, "Target does not use pinctrl\n");
		fpc1020->fingerprint_pinctrl = NULL;
		rc = -EINVAL;
		goto exit;
	}

	for (i = 0; i < ARRAY_SIZE(fpc1020->pinctrl_state); i++) {
		const char *n = pctl_names[i];
		struct pinctrl_state *state =
			pinctrl_lookup_state(fpc1020->fingerprint_pinctrl, n);
		if (IS_ERR(state)) {
			dev_err(dev, "cannot find '%s'\n", n);
			rc = -EINVAL;
			goto exit;
		}
		dev_info(dev, "found pin control %s\n", n);
		fpc1020->pinctrl_state[i] = state;
	}

	select_pin_ctl(fpc1020, "fpc1020_reset_active");
	udelay(100);
	select_pin_ctl(fpc1020, "fpc1020_reset_reset");
	udelay(1000);
	select_pin_ctl(fpc1020, "fpc1020_reset_active");
	udelay(1250);
	rc = select_pin_ctl(fpc1020, "fpc1020_irq_active");
	if (rc)
		goto exit;

	rc = select_pin_ctl(fpc1020, "fpc1020_spi_active");
	if (rc)
		goto exit;

	fpc1020->wakeup_enabled = false;
	fpc1020->clocks_enabled = false;
	fpc1020->clocks_suspended = false;
	irqf = IRQF_TRIGGER_RISING | IRQF_ONESHOT;
	if (of_property_read_bool(dev->of_node, "fpc,enable-wakeup")) {
		irqf |= IRQF_NO_SUSPEND;
		device_init_wakeup(dev, 1);
	}

	mutex_init(&fpc1020->lock);
	rc = devm_request_threaded_irq(dev, gpio_to_irq(fpc1020->irq_gpio),
			NULL, fpc1020_irq_handler, irqf,
			dev_name(dev), fpc1020);
	if (rc) {
		dev_err(dev, "could not request irq %d\n",
				gpio_to_irq(fpc1020->irq_gpio));
		goto exit;
	}

	dev_dbg(dev, "requested irq %d\n", gpio_to_irq(fpc1020->irq_gpio));

	/* Request that the interrupt should be wakeable */
	enable_irq_wake( gpio_to_irq( fpc1020->irq_gpio ) );

	wake_lock_init(&fpc1020->ttw_wl, WAKE_LOCK_SUSPEND, "fpc_ttw_wl");

	rc = sysfs_create_group(&dev->kobj, &attribute_group);
	if (rc) {
		dev_err(dev, "could not create sysfs\n");
		goto exit;
	}

	if (of_property_read_bool(dev->of_node, "fpc,enable-on-boot")) {
		dev_info(dev, "enabling hardware\n");
		(void)device_prepare(fpc1020, true);
		(void)set_clks(fpc1020, false);
	}

	dev_info(dev, "%s: end\n", __func__);
exit:
	return rc;
}
static int gp2a_opt_probe(struct platform_device *pdev)
{
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = pdev->dev.platform_data;
	u8 value = 0;
	int err = 0;

	gprintk("probe start!\n");

	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return err;
	}

	if (!pdata->gp2a_led_on) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return err;
	}
	/* gp2a power on */
	pdata->gp2a_led_on(true);

	if (pdata->gp2a_get_threshold) {
		gp2a_update_threshold(is_gp2a030a() ?
			gp2a_original_image_030a : gp2a_original_image,
			pdata->gp2a_get_threshold(), false);
	}

	/* allocate driver_data */
	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("kzalloc error\n");
		return -ENOMEM;
	}

	proximity_enable = 0;
	proximity_sensor_detection = 0;
	proximity_avg_on = 0;
	gp2a->enabled = 0;
	gp2a->pdata = pdata;

	/* prox_timer settings. we poll for prox_avg values using a timer. */
	hrtimer_init(&gp2a->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	gp2a->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);
	gp2a->prox_timer.function = gp2a_prox_timer_func;

	gp2a->prox_wq = create_singlethread_workqueue("gp2a_prox_wq");
	if (!gp2a->prox_wq) {
		err = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}

	INIT_WORK(&gp2a->work_prox, gp2a_work_func_prox_avg);
	INIT_WORK(&gp2a->work, gp2a_work_func_prox);

	err = proximity_input_init(gp2a);
	if (err < 0)
		goto error_setup_reg;

	err = sysfs_create_group(&gp2a->input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (err < 0)
		goto err_sysfs_create_group_proximity;

	/* set platdata */
	platform_set_drvdata(pdev, gp2a);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
		       "prx_wake_lock");

	/* init i2c */
	opt_i2c_init();

	if (opt_i2c_client == NULL) {
		pr_err("opt_probe failed : i2c_client is NULL\n");
		goto err_no_device;
	} else
		printk(KERN_INFO "opt_i2c_client : (0x%p), address = %x\n",
		       opt_i2c_client, opt_i2c_client->addr);

	/* GP2A Regs INIT SETTINGS  and Check I2C communication */
	value = 0x00;
	/* shutdown mode op[3]=0 */
	err = opt_i2c_write((u8) (COMMAND1), &value);

	if (err < 0) {
		pr_err("%s failed : threre is no such device.\n", __func__);
		goto err_no_device;
	}

	/* Setup irq */
	err = gp2a_setup_irq(gp2a);
	if (err) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* set sysfs for proximity sensor */
	gp2a->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(gp2a->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	if (device_create_file(gp2a->proximity_dev, &dev_attr_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_state.attr.name);
		goto err_proximity_device_create_file1;
	}

	if (device_create_file(gp2a->proximity_dev, &dev_attr_prox_avg) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_prox_avg.attr.name);
		goto err_proximity_device_create_file2;
	}

	if (device_create_file(gp2a->proximity_dev,
						&dev_attr_prox_thresh) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_prox_thresh.attr.name);
		goto err_proximity_device_create_file3;
	}

	if (device_create_file(gp2a->proximity_dev,
						&dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_vendor.attr.name);
		goto err_proximity_device_create_file4;
	}

	if (device_create_file(gp2a->proximity_dev,
						&dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_name.attr.name);
		goto err_proximity_device_create_file5;
	}

	if (device_create_file(gp2a->proximity_dev, &dev_attr_raw_data) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
		       dev_attr_raw_data.attr.name);
		goto err_proximity_device_create_file6;
	}

#ifdef CONFIG_SLP
	device_init_wakeup(gp2a->proximity_dev, true);
#endif
	dev_set_drvdata(gp2a->proximity_dev, gp2a);

	device_init_wakeup(&pdev->dev, 1);

	gprintk("probe success!\n");

	return 0;

err_proximity_device_create_file6:
	device_remove_file(gp2a->proximity_dev, &dev_attr_raw_data);
err_proximity_device_create_file5:
	device_remove_file(gp2a->proximity_dev, &dev_attr_name);
err_proximity_device_create_file4:
	device_remove_file(gp2a->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file3:
	device_remove_file(gp2a->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file2:
	device_remove_file(gp2a->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(gp2a->proximity_dev);
err_proximity_device_create:
	gpio_free(pdata->p_out);
err_setup_irq:
err_no_device:
	sysfs_remove_group(&gp2a->input_dev->dev.kobj,
			   &proximity_attribute_group);
	wake_lock_destroy(&gp2a->prx_wake_lock);
err_sysfs_create_group_proximity:
	input_unregister_device(gp2a->input_dev);
error_setup_reg:
	destroy_workqueue(gp2a->prox_wq);
err_create_prox_workqueue:
	kfree(gp2a);
	return err;
}
示例#9
0
int nvme_nvm_register_sysfs(struct nvme_ns *ns)
{
	return sysfs_create_group(&disk_to_dev(ns->disk)->kobj,
					&nvm_dev_attr_group);
}
示例#10
0
// Pantech Earjack Probe Function
static int __devinit pantech_earjack_probe(struct platform_device *pdev)
{
	int rc = 0;
	int err = 0;
	struct input_dev *ipdev;

	dbg_func_in();

	irq_state = 0;

	// Alloc Devices
	earjack = kzalloc(sizeof(struct pantech_earjack), GFP_KERNEL);
	if (!earjack)
		return -ENOMEM;

	earjack->sdev.name	= "h2w";   
  
	earjack->sdev.print_name = msm_headset_print_name;
	rc = switch_dev_register(&earjack->sdev);
	if (rc)
		goto err_switch_dev_register;

	ipdev = input_allocate_device();
	if (!ipdev) {
		rc = -ENOMEM;
		goto err_alloc_input_dev;
	}
	input_set_drvdata(ipdev, earjack);


	// Init Status Flags
	earjack->ipdev = ipdev;
	earjack->car_kit = 0;
	earjack->type=EARJACK_STATE_OFF;
	earjack->remotekey_pressed = 0;
	earjack->remotekey_index = 0;

	// Initialize Work Queue
	INIT_DELAYED_WORK(&earjack_work,earjack_detect_func);          // INIT WORK
	INIT_DELAYED_WORK(&remotekey_work,remotekey_detect_func);

	// Get Power Source
#if defined(CONFIG_MIC_BIAS_1_8V)
	err = 0;
#else
	hs_jack_l8 = regulator_get(NULL, "8058_l8");
	regulator_set_voltage(hs_jack_l8,2700000,2700000);

	dbg("regulator_enable hs_jack_l8 value => %d\n",err);
#endif

	// Initialize Wakelocks
	wake_lock_init(&earjack_wake_lock, WAKE_LOCK_SUSPEND, "earjack_wake_lock_init");
	wake_lock_init(&remotekey_wake_lock, WAKE_LOCK_SUSPEND, "remotekey_wake_lock_init");

	// Setup GPIO's
	gpio_request(EARJACK_DET, "earjack_det");
	gpio_request(REMOTEKEY_DET, "remotekey_det");
	gpio_tlmm_config(GPIO_CFG(EARJACK_DET, 0, GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
	rc = request_irq(gpio_to_irq(EARJACK_DET), Earjack_Det_handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "earjack_det-irq", earjack);

	// Warning: REMOTEKEY_DET using default gpio config.
	//gpio_tlmm_config(GPIO_CFG(REMOTEKEY_DET, 0, GPIO_CFG_INPUT,GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_ENABLE);
	
	irq_set_irq_wake(gpio_to_irq(EARJACK_DET), 1);
	irq_set_irq_wake(gpio_to_irq(REMOTEKEY_DET), 1);

	// Init Input Device
//pz1946 merge for wired long key
#ifdef CONFIG_MACH_MSM8X60_PRESTO
	ipdev->name	= DRIVER_NAME;
	ipdev->id.vendor    = 0;
	ipdev->id.product   = 0;
	ipdev->id.version   = 0;
#else	
	ipdev->id.vendor    = 0x0001;
	ipdev->id.product   = 1;
	ipdev->id.version   = 1;
#endif

	input_set_capability(ipdev, EV_KEY, KEY_MEDIA);
	input_set_capability(ipdev, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(ipdev, EV_KEY, KEY_VOLUMEDOWN);
	input_set_capability(ipdev, EV_KEY, KEY_POWER);    
	input_set_capability(ipdev, EV_KEY, KEY_END);
	input_set_capability(ipdev, EV_SW,  SW_HEADPHONE_INSERT);
	input_set_capability(ipdev, EV_SW,  SW_MICROPHONE_INSERT);

	rc = input_register_device(ipdev);
	if (rc) {
		dev_err(&ipdev->dev,
				"hs_probe: input_register_device rc=%d\n", rc);
		goto err_reg_input_dev;
	}
	platform_set_drvdata(pdev, earjack);

	rc = sysfs_create_group(&pdev->dev.kobj, &dev_attr_grp);
	if (rc) {
		dev_err(&ipdev->dev,
				"hs_probe: sysfs_create_group rc=%d\n", rc);
		goto err_earjack_init;
	}

	// Scehdule earjack_detect_func for initial detect
	disable_irq_detect(); //disable_irq_nosync(gpio_to_irq(EARJACK_DET));
	
	wake_lock(&earjack_wake_lock);
	disable_irq_nosync(gpio_to_irq(REMOTEKEY_DET));

	schedule_delayed_work(&earjack_work,10);    // after 100ms
	
	dbg_func_out();
	return 0;

err_earjack_init:

err_reg_input_dev:
	input_unregister_device(ipdev);
	ipdev = NULL;
err_alloc_input_dev:
	input_free_device(ipdev);
err_switch_dev_register:
	kfree(earjack);
	return 0;
}
static int __devinit max14577_muic_probe(struct platform_device *pdev)
{
	struct max14577_dev *max14577 = dev_get_drvdata(pdev->dev.parent);
	struct max14577_platform_data *mfd_pdata = dev_get_platdata(max14577->dev);
	struct max14577_muic_data *muic_data;
	u8 ctrl2 = 0;
	int ret = 0;

	muic_data = kzalloc(sizeof(struct max14577_muic_data), GFP_KERNEL);
	if (!muic_data) {
		pr_err("%s: failed to allocate driver data\n", __func__);
		ret = -ENOMEM;
		goto err_return;
	}

	if (!mfd_pdata) {
		pr_err("%s: failed to get max14577 mfd platform data\n", __func__);
		ret = -ENOMEM;
		goto err_kfree;
	}

	muic_data->dev = &pdev->dev;
	mutex_init(&muic_data->muic_mutex);
	muic_data->i2c = max14577->i2c;
	muic_data->mfd_pdata = mfd_pdata;
	muic_data->irq_adcerr = mfd_pdata->irq_base + MAX14577_IRQ_INT1_ADCERR;
	muic_data->irq_adc = mfd_pdata->irq_base + MAX14577_IRQ_INT1_ADC;
	muic_data->irq_chgtyp = mfd_pdata->irq_base + MAX14577_IRQ_INT2_CHGTYP;
	muic_data->irq_vbvolt = mfd_pdata->irq_base + MAX14577_IRQ_INT2_VBVOLT;
	muic_data->switch_data = &sec_switch_data;
	muic_data->attached_dev = ATTACHED_DEV_UNKNOWN_MUIC;
	muic_data->is_usb_ready = false;
	muic_data->is_muic_ready = false;

	pr_info("%s:%s irq_num: adcerr(%d), adc(%d), chgtyp(%d), vbvolt(%d)\n",
			MUIC_DEV_NAME, __func__, muic_data->irq_adcerr,
			muic_data->irq_adc, muic_data->irq_chgtyp,
			muic_data->irq_vbvolt);

	platform_set_drvdata(pdev, muic_data);

	/* Set ADC debounce time: 25ms */
	max14577_muic_set_adcdbset(muic_data, 2);

	/* Set Charger-Detection Check Time: 625ms */
	max14577_muic_set_dchktm(muic_data, 1);

	ret = max14577_read_reg(muic_data->i2c, MAX14577_REG_CONTROL2, &ctrl2);
	if (ret) {
		pr_err("%s:%s fail to read CTRL2 (%d)\n", MUIC_DEV_NAME, __func__, ret);
		goto fail;
	}

	pr_info("%s:%s: ctrl2:0x%x\n", MUIC_DEV_NAME, __func__, ctrl2);

	/* create sysfs group */
	ret = sysfs_create_group(&switch_device->kobj, &max14577_muic_group);
	if (ret) {
		pr_err("%s: failed to create max14577 muic attribute group\n",
				__func__);
		goto fail;
	}
	dev_set_drvdata(switch_device, muic_data);

	if (muic_data->switch_data->init_cb)
		muic_data->switch_data->init_cb();

	ret = max14577_muic_irq_init(muic_data);
	if (ret < 0) {
		dev_err(&pdev->dev, "Failed to initialize MUIC irq:%d\n", ret);
		goto fail_init_irq;
	}

	/* initial cable detection */
	INIT_DELAYED_WORK(&muic_data->init_work, max14577_muic_init_detect);
	schedule_delayed_work(&muic_data->init_work,
			msecs_to_jiffies(3000));

	INIT_DELAYED_WORK(&muic_data->usb_work, max14577_muic_usb_detect);
	schedule_delayed_work(&muic_data->usb_work, msecs_to_jiffies(17000));

	return 0;

fail_init_irq:
	if (muic_data->irq_adcerr)
		free_irq(muic_data->irq_adcerr, NULL);
	if (muic_data->irq_adc)
		free_irq(muic_data->irq_adc, NULL);
	if (muic_data->irq_chgtyp)
		free_irq(muic_data->irq_chgtyp, NULL);
	if (muic_data->irq_vbvolt)
		free_irq(muic_data->irq_vbvolt, NULL);
fail:
	platform_set_drvdata(pdev, NULL);
	mutex_destroy(&muic_data->muic_mutex);
err_kfree:
	kfree(muic_data);
err_return:
	return ret;
}
示例#12
0
static void __init buzz_init(void)
{
	int rc;
	char *cid = NULL;
	struct kobject *properties_kobj;

	printk("buzz_init() revision = 0x%X\n", system_rev);
	msm_clock_init();
	board_get_cid_tag(&cid);

	/* for bcm */
	bt_export_bd_address();

	/*
	 * Setup common MSM GPIOS
	 */
	config_gpios();

	/* We need to set this pin to 0 only once on power-up; we will
	 * not actually enable the chip until we apply power to it via
	 * vreg.
	 */
	gpio_request(BUZZ_GPIO_LS_EN, "ls_en");
	gpio_direction_output(BUZZ_GPIO_LS_EN, 0);

	gpio_request(BUZZ_PS_2V85_EN, "ps_2v85_en");

	msm_hw_reset_hook = buzz_reset;

	msm_acpu_clock_init(&buzz_clock_data);
#ifdef CONFIG_PERFLOCK
	perflock_init(&buzz_perflock_data);
#endif

#if defined(CONFIG_MSM_SERIAL_DEBUGGER)
	if (!opt_disable_uart3)
		msm_serial_debug_init(MSM_UART3_PHYS, INT_UART3,
			&msm_device_uart3.dev, 1,
				MSM_GPIO_TO_INT(BUZZ_GPIO_UART3_RX));
#endif

#ifdef CONFIG_SERIAL_MSM_HS
	msm_device_uart_dm1.dev.platform_data = &msm_uart_dm1_pdata;
#ifndef CONFIG_SERIAL_MSM_HS_PURE_ANDROID
	msm_device_uart_dm1.name = "msm_serial_hs_bcm";	/* for bcm */
#endif
	msm_add_serial_devices(3);
#else
	msm_add_serial_devices(0);
#endif

	msm_add_serial_devices(2);
#ifdef CONFIG_USB_FUNCTION
	msm_register_usb_phy_init_seq(buzz_phy_init_seq);
	msm_add_usb_id_pin_gpio(BUZZ_GPIO_USB_ID_PIN);
	msm_add_usb_devices(buzz_phy_reset, NULL);
#endif

#ifdef CONFIG_USB_ANDROID
	android_usb_pdata.products[0].product_id =
		android_usb_pdata.product_id;
	android_usb_pdata.serial_number = board_serialno();
	msm_hsusb_pdata.serial_number = board_serialno();
	msm_device_hsusb.dev.platform_data = &msm_hsusb_pdata;
	platform_device_register(&msm_device_hsusb);
#ifdef CONFIG_USB_ANDROID_RNDIS
	platform_device_register(&rndis_device);
#endif
	platform_device_register(&usb_mass_storage_device);
	platform_device_register(&android_usb_device);
#endif
	msm_add_mem_devices(&pmem_setting);

#ifdef CONFIG_MICROP_COMMON
	buzz_microp_init();
#endif

	rc = buzz_init_mmc(system_rev);
	if (rc)
		printk(KERN_CRIT "%s: MMC init failure (%d)\n", __func__, rc);

	properties_kobj = kobject_create_and_add("board_properties", NULL);

	if (properties_kobj)
		rc = sysfs_create_group(properties_kobj,
					 &buzz_properties_attr_group);
	if (!properties_kobj || rc)
		pr_err("failed to create board_properties\n");

	msm_device_i2c_init();
	platform_add_devices(devices, ARRAY_SIZE(devices));
	i2c_register_board_info(0, i2c_devices, ARRAY_SIZE(i2c_devices));

	if (system_rev < 3) {
		i2c_microp_devices.platform_data = &microp_data_xc;
		platform_device_register(&buzz_leds);
	}
	if (system_rev >= 4) {
		platform_device_register(&buzz_oj);

	}
	i2c_register_board_info(0, &i2c_microp_devices, 1);

	/* probe camera driver */
	i2c_register_board_info(0, i2c_camera_devices, ARRAY_SIZE(i2c_camera_devices));

	buzz_init_keypad();
	buzz_wifi_init();
	buzz_panel_init();

	msm_init_pmic_vibrator(3000);
}
static int __devinit pm8xxx_vib_probe(struct platform_device *pdev)

{
	const struct pm8xxx_vibrator_platform_data *pdata =
						pdev->dev.platform_data;
	struct pm8xxx_vib *vib;
	u8 val;
	int rc;

	if (!pdata)
		return -EINVAL;

	if (pdata->level_mV < VIB_MIN_LEVEL_mV ||
			 pdata->level_mV > VIB_MAX_LEVEL_mV)
		return -EINVAL;

	vib = kzalloc(sizeof(*vib), GFP_KERNEL);
	if (!vib)
		return -ENOMEM;

	vib->pdata	= pdata;
	vib->level	= pdata->level_mV / 100;
	vib->dev	= &pdev->dev;

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_VOL
	vib->default_level  = vib->level;
	vib->request_level  = vib->level;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_MIN_TIMEOUT
	vib->min_timeout_ms  = pdata->min_timeout_ms;
	vib->pre_value  = 0;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_OVERDRIVE
	vib->overdrive_ms  = pdata->overdrive_ms;
	vib->overdrive_range_ms  = pdata->overdrive_range_ms;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_REST_POWER
	vib->min_stop_ms  = pdata->min_stop_ms;
	vib->start_tv.tv_sec = 0;
	vib->start_tv.tv_usec = 0;
	vib->stop_tv.tv_sec = 0;
	vib->stop_tv.tv_usec = 0;
#endif

    vib->max_level_mv = VIB_MAX_LEVEL_mV;
    vib->min_level_mv = VIB_MIN_LEVEL_mV;

	spin_lock_init(&vib->lock);
	INIT_WORK(&vib->work, pm8xxx_vib_update);

	hrtimer_init(&vib->vib_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_timer.function = pm8xxx_vib_timer_func;

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_OVERDRIVE
	hrtimer_init(&vib->vib_overdrive_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	vib->vib_overdrive_timer.function = pm8xxx_vib_overdrive_timer_func;
#endif

	vib->timed_dev.name = "vibrator";
	vib->timed_dev.get_time = pm8xxx_vib_get_time;
	vib->timed_dev.enable = pm8xxx_vib_enable;

	__dump_vib_regs(vib, "boot_vib_default");

	/*
	 * Configure the vibrator, it operates in manual mode
	 * for timed_output framework.
	 */
	rc = pm8xxx_vib_read_u8(vib, &val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;
	val &= ~VIB_DRV_EN_MANUAL_MASK;
	rc = pm8xxx_vib_write_u8(vib, val, VIB_DRV);
	if (rc < 0)
		goto err_read_vib;

	vib->reg_vib_drv = val;

	rc = timed_output_dev_register(&vib->timed_dev);
	if (rc < 0)
		goto err_read_vib;

    rc = sysfs_create_group(&vib->timed_dev.dev->kobj, &pm8xxx_vib_attr_group);

#if 0

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_VOL
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_amp);
	if (rc < 0)
		goto err_read_vib;

	rc = device_create_file(vib->timed_dev.dev, &dev_attr_default_level);
	if (rc < 0)
		goto err_read_vib;
#endif

// LGE does not use this function. power on vib effect is played at SBL3
#ifndef CONFIG_MACH_LGE
	pm8xxx_vib_enable(&vib->timed_dev, pdata->initial_vibrate_ms);
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_MIN_TIMEOUT
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_min_ms);
	if (rc < 0)
		goto err_read_vib;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_OVERDRIVE
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_over_ms);
	if (rc < 0)
		goto err_read_vib;

	rc = device_create_file(vib->timed_dev.dev, &dev_attr_over_range_ms);
	if (rc < 0)
		goto err_read_vib;
#endif

#ifdef CONFIG_LGE_PMIC8XXX_VIBRATOR_REST_POWER
	rc = device_create_file(vib->timed_dev.dev, &dev_attr_min_stop_ms);
	if (rc < 0)
		goto err_read_vib;
#endif

#endif // #if 0
	platform_set_drvdata(pdev, vib);

	vib_dev = vib;

	return 0;

err_read_vib:
	kfree(vib);
	return rc;
}
static int wacom_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	static struct wacom_g5_platform_data *pdata; // = client->dev.platform_data;
	struct wacom_i2c *wac_i2c;
	struct input_dev *input;
	int ret = 0;



#ifdef CONFIG_OF
	printk(KERN_ERR "epen: %s, start,%d\n",__func__, __LINE__);

	pdata = kzalloc(sizeof(struct wacom_g5_platform_data), GFP_KERNEL);
	if (!pdata) {
		printk(KERN_ERR "epen: pdata err = ENOMEM!\n");
		return -ENOMEM;
	}

	pdata->x_invert = WACOM_X_INVERT;
	pdata->y_invert = WACOM_Y_INVERT;
	pdata->xy_switch = WACOM_XY_SWITCH;
	pdata->min_x = 0;
	pdata->max_x = WACOM_MAX_COORD_X;
	pdata->min_y = 0;
	pdata->max_y = WACOM_MAX_COORD_Y;
	pdata->min_pressure = 0;
	pdata->max_pressure = WACOM_MAX_PRESSURE;
	pdata->suspend_platform_hw = wacom_suspend_hw;
	pdata->resume_platform_hw = wacom_resume_hw;
	pdata->reset_platform_hw = wacom_reset_hw;
	pdata->register_cb = wacom_register_callbacks;
	pdata->compulsory_flash_mode = wacom_compulsory_flash_mode;

	pdata->get_irq_state = wacom_get_irq_state;

	ret = wacom_parse_dt(&client->dev, pdata);

	if (ret) {
		printk(KERN_ERR "Error parsing dt %d\n", ret);
		return ret;
	}

	wacom_init_gpio(pdata);

#else
	printk(KERN_ERR "epen: %s, start,%d\n",__func__, __LINE__);

	if (pdata == NULL) {
		printk(KERN_ERR "epen: %s: no pdata\n", __func__);
		ret = -ENODEV;
		goto err_i2c_fail;
	}
#endif

	/*Check I2C functionality */
	ret = i2c_check_functionality(client->adapter, I2C_FUNC_I2C);
	if (!ret) {
		printk(KERN_ERR "epen:No I2C functionality found\n");
		ret = -ENODEV;
		goto err_i2c_fail;
	}

	/*Obtain kernel memory space for wacom i2c */
	wac_i2c = kzalloc(sizeof(struct wacom_i2c), GFP_KERNEL);
	if (NULL == wac_i2c) {
		printk(KERN_ERR "epen:failed to allocate wac_i2c.\n");
		ret = -ENOMEM;
		goto err_alloc_mem;
	}

	wac_i2c->client_boot = i2c_new_dummy(client->adapter,
		WACOM_I2C_BOOT);
	if (!wac_i2c->client_boot) {
		dev_err(&client->dev, "Fail to register sub client[0x%x]\n",
			 WACOM_I2C_BOOT);
	}

	input = input_allocate_device();
	if (NULL == input) {
		printk(KERN_ERR "epen:failed to allocate input device.\n");
		ret = -ENOMEM;
		goto err_alloc_input_dev;
	}

	wacom_i2c_set_input_values(client, wac_i2c, input);

	wac_i2c->wac_feature = &wacom_feature_EMR;
	wac_i2c->wac_pdata = pdata;
	wac_i2c->input_dev = input;
	wac_i2c->client = client;

	//wac_i2c->irq = client->irq;
	wac_i2c->irq = gpio_to_irq(pdata->gpio_irq); 	//dtsi

	//printk(KERN_ERR "epen: irq %d, %d, %d\n", wac_i2c->irq, pdata->gpio_irq, client->irq);
	irq_set_irq_type(wac_i2c->irq, IRQ_TYPE_EDGE_RISING);	// dtsi

	/* init_completion(&wac_i2c->init_done); */
#ifdef WACOM_PDCT_WORK_AROUND
	wac_i2c->irq_pdct = gpio_to_irq(pdata->gpio_pendct);
	wac_i2c->pen_pdct = PDCT_NOSIGNAL;

	irq_set_irq_type(wac_i2c->irq_pdct , IRQ_TYPE_EDGE_BOTH);	// dtsi
#endif
#ifdef WACOM_PEN_DETECT
	wac_i2c->gpio_pen_insert = pdata->gpio_pen_insert;
#endif
#ifdef WACOM_IMPORT_FW_ALGO
	wac_i2c->use_offset_table = true;
	wac_i2c->use_aveTransition = false;
	wacom_init_fw_algo(wac_i2c);
#endif

	/*Change below if irq is needed */
	wac_i2c->irq_flag = 1;

	/*Register callbacks */
	wac_i2c->callbacks.check_prox = wacom_check_emr_prox;
	if (wac_i2c->wac_pdata->register_cb)
		wac_i2c->wac_pdata->register_cb(&wac_i2c->callbacks);

	/* Firmware Feature */
	wacom_i2c_init_firm_data();

	/* Power on */
	wac_i2c->wac_pdata->resume_platform_hw();
	msleep(60); // for booting time,  msleep(200);
	wac_i2c->power_enable = true;
	wac_i2c->pwr_flag = true;

	printk(KERN_ERR "epen: %s, query, %d\n", __func__, __LINE__);
	wacom_i2c_query(wac_i2c);

	wacom_init_abs_params(wac_i2c);
	input_set_drvdata(input, wac_i2c);

	/*Change below if irq is needed */
	wac_i2c->irq_flag = 1;

	/*Set client data */
	i2c_set_clientdata(client, wac_i2c);
	i2c_set_clientdata(wac_i2c->client_boot, wac_i2c);

	/*Initializing for semaphor */
	mutex_init(&wac_i2c->lock);
	mutex_init(&wac_i2c->update_lock);
	mutex_init(&wac_i2c->irq_lock);
	wake_lock_init(&wac_i2c->fw_wakelock, WAKE_LOCK_SUSPEND, "wacom");
	INIT_DELAYED_WORK(&wac_i2c->resume_work, wacom_i2c_resume_work);
#ifdef LCD_FREQ_SYNC
	mutex_init(&wac_i2c->freq_write_lock);
	INIT_WORK(&wac_i2c->lcd_freq_work, wacom_i2c_lcd_freq_work);
	INIT_DELAYED_WORK(&wac_i2c->lcd_freq_done_work, wacom_i2c_finish_lcd_freq_work);
	if (likely(system_rev >= LCD_FREQ_SUPPORT_HWID))
		wac_i2c->use_lcd_freq_sync = true;
#endif
#ifdef WACOM_USE_SOFTKEY_BLOCK
	INIT_DELAYED_WORK(&wac_i2c->softkey_block_work, wacom_i2c_block_softkey_work);
	wac_i2c->block_softkey = false;
#endif
	INIT_WORK(&wac_i2c->update_work, wacom_i2c_update_work);
	/*init wacom booster*/
#if defined(WACOM_BOOSTER_DVFS)
	wacom_init_dvfs(wac_i2c);
#elif defined(WACOM_BOOSTER)
	wacom_init_dvfs(wac_i2c);
	wac_i2c->boost_level = WACOM_BOOSTER_LEVEL2;
#endif
	printk(KERN_ERR "epen: %s,%d \n", __func__, __LINE__);

	/*Before registering input device, data in each input_dev must be set */
	ret = input_register_device(input);
	if (ret) {
		pr_err("epen:failed to register input device.\n");
		goto err_register_device;
	}

#ifdef CONFIG_HAS_EARLYSUSPEND
	wac_i2c->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	wac_i2c->early_suspend.suspend = wacom_i2c_early_suspend;
	wac_i2c->early_suspend.resume = wacom_i2c_late_resume;
	register_early_suspend(&wac_i2c->early_suspend);
#endif

	wac_i2c->dev = device_create(sec_class, NULL, 0, NULL, "sec_epen");
	if (IS_ERR(wac_i2c->dev)) {
		printk(KERN_ERR "Failed to create device(wac_i2c->dev)!\n");
		ret = -ENODEV;
		goto err_create_device;
	}

	dev_set_drvdata(wac_i2c->dev, wac_i2c);

	ret = sysfs_create_group(&wac_i2c->dev->kobj, &epen_attr_group);
	if (ret) {
		printk(KERN_ERR
			    "epen:failed to create sysfs group\n");
		goto err_sysfs_create_group;
	}

	/* firmware info */
	printk(KERN_NOTICE "epen:wacom fw ver : 0x%x, new fw ver : 0x%x\n",
	       wac_i2c->wac_feature->fw_version, fw_ver_file);

	/*Request IRQ */
	if (wac_i2c->irq_flag) {
		ret =
		    request_threaded_irq(wac_i2c->irq, NULL, wacom_interrupt,
					 IRQF_DISABLED | EPEN_IRQF_TRIGGER_TYPE |
					 IRQF_ONESHOT, "sec_epen_irq", wac_i2c);
		if (ret < 0) {
			printk(KERN_ERR
			       "epen:failed to request irq(%d) - %d\n",
			       wac_i2c->irq, ret);
			goto err_request_irq;
		}
		printk(KERN_ERR "epen: %s,%d \n", __func__, __LINE__);

#if defined(WACOM_PDCT_WORK_AROUND)
		ret =
			request_threaded_irq(wac_i2c->irq_pdct, NULL,
					wacom_interrupt_pdct,
					IRQF_DISABLED | IRQF_TRIGGER_RISING |
					IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
					"sec_epen_pdct", wac_i2c);
		if (ret < 0) {
			printk(KERN_ERR
				"epen:failed to request irq(%d) - %d\n",
				wac_i2c->irq_pdct, ret);
			goto err_request_irq;
		}
#endif
	}
#ifdef WACOM_PEN_DETECT
	init_pen_insert(wac_i2c);
#endif
	printk(KERN_ERR "epen: %s,%d \n", __func__, __LINE__);

	wac_i2c->update_info.forced = false;
	wac_i2c->update_info.fw_path = FW_BUILT_IN;
	schedule_work(&wac_i2c->update_work);
	/*complete_all(&wac_i2c->init_done);*/


	printk(KERN_ERR "epen: %s, -end %d\n", __func__, __LINE__);

	return 0;

 err_request_irq:
	wake_lock_destroy(&wac_i2c->fw_wakelock);
	sysfs_remove_group(&wac_i2c->dev->kobj,
		&epen_attr_group);
 err_sysfs_create_group:
	device_destroy(sec_class, (dev_t)NULL);
 err_create_device:
	input_unregister_device(input);
	input = NULL;
 err_register_device:
#ifdef LCD_FREQ_SYNC
	mutex_destroy(&wac_i2c->freq_write_lock);
#endif
	mutex_destroy(&wac_i2c->irq_lock);
	mutex_destroy(&wac_i2c->update_lock);
	mutex_destroy(&wac_i2c->lock);
	input_free_device(input);
 err_alloc_input_dev:
	kfree(wac_i2c);
	wac_i2c = NULL;
 err_alloc_mem:
 err_i2c_fail:
	return ret;
}
static int
aoedisk_add_sysfs(struct aoedev *d)
{
	return sysfs_create_group(&disk_to_dev(d->gd)->kobj, &attr_group);
}
static int __devinit gpio_keys_probe(struct platform_device *pdev)
{
    const struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
    struct gpio_keys_drvdata *ddata;
    struct device *dev = &pdev->dev;
    struct gpio_keys_platform_data alt_pdata;
    struct input_dev *input;
    int i, error;
    int wakeup = 0;

    if (!pdata) {
        error = gpio_keys_get_devtree_pdata(dev, &alt_pdata);
        if (error)
            return error;
        pdata = &alt_pdata;
    }

    ddata = kzalloc(sizeof(struct gpio_keys_drvdata) +
                    pdata->nbuttons * sizeof(struct gpio_button_data),
                    GFP_KERNEL);
    input = input_allocate_device();
    if (!ddata || !input) {
        dev_err(dev, "failed to allocate state\n");
        error = -ENOMEM;
        goto fail1;
    }

    ddata->input = input;
    ddata->n_buttons = pdata->nbuttons;
    ddata->enable = pdata->enable;
    ddata->disable = pdata->disable;
    mutex_init(&ddata->disable_lock);

    platform_set_drvdata(pdev, ddata);
    input_set_drvdata(input, ddata);

    input->name = pdata->name ? : pdev->name;
    input->phys = "gpio-keys/input0";
    input->dev.parent = &pdev->dev;
    input->open = gpio_keys_open;
    input->close = gpio_keys_close;

    input->id.bustype = BUS_HOST;
    input->id.vendor = 0x0001;
    input->id.product = 0x0001;
    input->id.version = 0x0100;

    /* Enable auto repeat feature of Linux input subsystem */
    if (pdata->rep)
        __set_bit(EV_REP, input->evbit);

    for (i = 0; i < pdata->nbuttons; i++) {
        const struct gpio_keys_button *button = &pdata->buttons[i];
        struct gpio_button_data *bdata = &ddata->data[i];

        error = gpio_keys_setup_key(pdev, input, bdata, button);
        if (error)
            goto fail2;

        if (button->wakeup)
            wakeup = 1;
    }

    error = sysfs_create_group(&pdev->dev.kobj, &gpio_keys_attr_group);
    if (error) {
        dev_err(dev, "Unable to export keys/switches, error: %d\n",
                error);
        goto fail2;
    }

    error = input_register_device(input);
    if (error) {
        dev_err(dev, "Unable to register input device, error: %d\n",
                error);
        goto fail3;
    }

    /* get current state of buttons that are connected to GPIOs */
    for (i = 0; i < pdata->nbuttons; i++) {
        struct gpio_button_data *bdata = &ddata->data[i];
        if (gpio_is_valid(bdata->button->gpio))
            gpio_keys_gpio_report_event(bdata);
    }
    input_sync(input);

    device_init_wakeup(&pdev->dev, wakeup);

    return 0;

fail3:
    sysfs_remove_group(&pdev->dev.kobj, &gpio_keys_attr_group);
fail2:
    while (--i >= 0)
        gpio_remove_key(&ddata->data[i]);

    platform_set_drvdata(pdev, NULL);
fail1:
    input_free_device(input);
    kfree(ddata);
    /* If we have no platform_data, we allocated buttons dynamically. */
    if (!pdev->dev.platform_data)
        kfree(pdata->buttons);

    return error;
}
static int cm36686_i2c_probe(struct i2c_client *client,
				const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct cm36686_data *cm36686 = NULL;

	pr_info("%s is called.\n", __func__);
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	cm36686 = kzalloc(sizeof(struct cm36686_data), GFP_KERNEL);
	if (!cm36686) {
		pr_err("%s: failed to alloc memory for cm36686 module data\n",
			__func__);
		return -ENOMEM;
	}

	cm36686->pdata = client->dev.platform_data;
	cm36686->i2c_client = client;
	i2c_set_clientdata(client, cm36686);
	mutex_init(&cm36686->power_lock);
	mutex_init(&cm36686->read_lock);

	/* wake lock init for proximity sensor */
	wake_lock_init(&cm36686->prx_wake_lock, WAKE_LOCK_SUSPEND,
			"prx_wake_lock");
	if (cm36686->pdata->cm36686_led_on) {
		cm36686->pdata->cm36686_led_on(true);
		msleep(20);
	}
	/* Check if the device is there or not. */
	ret = cm36686_i2c_write_word(cm36686, REG_CS_CONF1, 0x0001);
	if (ret < 0) {
		pr_err("%s: cm36686 is not connected.(%d)\n", __func__, ret);
		goto err_setup_reg;
	}

	/* setup initial registers */
	ret = cm36686_setup_reg(cm36686);
	if (ret < 0) {
		pr_err("%s: could not setup regs\n", __func__);
		goto err_setup_reg;
	}
	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);

	/* allocate proximity input_device */
	cm36686->proximity_input_dev = input_allocate_device();
	if (!cm36686->proximity_input_dev) {
		pr_err("%s: could not allocate proximity input device\n",
			__func__);
		goto err_input_allocate_device_proximity;
	}

	input_set_drvdata(cm36686->proximity_input_dev, cm36686);
	cm36686->proximity_input_dev->name = "proximity_sensor";
	input_set_capability(cm36686->proximity_input_dev, EV_ABS,
			ABS_DISTANCE);
	input_set_abs_params(cm36686->proximity_input_dev, ABS_DISTANCE, 0, 1,
			0, 0);

	ret = input_register_device(cm36686->proximity_input_dev);
	if (ret < 0) {
		input_free_device(cm36686->proximity_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_proximity;
	}

	ret = sysfs_create_group(&cm36686->proximity_input_dev->dev.kobj,
				 &proximity_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->proximity_input_dev);
	if (ret < 0) {
		pr_err("%s - proximity_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_proximity_sensor_register_failed;
	}
#endif
	/* setup irq */
	ret = cm36686_setup_irq(cm36686);
	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	/* For factory test mode, we use timer to get average proximity data. */
	/* prox_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->prox_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->prox_poll_delay = ns_to_ktime(2000 * NSEC_PER_MSEC);/*2 sec*/
	cm36686->prox_timer.function = cm36686_prox_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm36686->prox_wq = create_singlethread_workqueue("cm36686_prox_wq");
	if (!cm36686->prox_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create prox workqueue\n", __func__);
		goto err_create_prox_workqueue;
	}
	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm36686->work_prox, cm36686_work_func_prox);

	/* allocate lightsensor input_device */
	cm36686->light_input_dev = input_allocate_device();
	if (!cm36686->light_input_dev) {
		pr_err("%s: could not allocate light input device\n", __func__);
		goto err_input_allocate_device_light;
	}

	input_set_drvdata(cm36686->light_input_dev, cm36686);
	cm36686->light_input_dev->name = "light_sensor";
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_MISC);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_DIAL);
	input_set_capability(cm36686->light_input_dev, EV_REL, REL_WHEEL);

	ret = input_register_device(cm36686->light_input_dev);
	if (ret < 0) {
		input_free_device(cm36686->light_input_dev);
		pr_err("%s: could not register input device\n", __func__);
		goto err_input_register_device_light;
	}

	ret = sysfs_create_group(&cm36686->light_input_dev->dev.kobj,
				 &light_attribute_group);
	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_light;
	}
#if defined(CONFIG_SENSOR_USE_SYMLINK)
	ret =  sensors_initialize_symlink(cm36686->light_input_dev);
	if (ret < 0) {
		pr_err("%s - light_sensors_initialize_symlink error(%d).\n",
                        __func__, ret);
		goto err_light_sensor_register_failed;
	}
#endif
	/* light_timer settings. we poll for light values using a timer. */
	hrtimer_init(&cm36686->light_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	cm36686->light_poll_delay = ns_to_ktime(200 * NSEC_PER_MSEC);
	cm36686->light_timer.function = cm36686_light_timer_func;

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	cm36686->light_wq = create_singlethread_workqueue("cm36686_light_wq");
	if (!cm36686->light_wq) {
		ret = -ENOMEM;
		pr_err("%s: could not create light workqueue\n", __func__);
		goto err_create_light_workqueue;
	}

	/* this is the thread function we run on the work queue */
	INIT_WORK(&cm36686->work_light, cm36686_work_func_light);

	/* set sysfs for proximity sensor */
	cm36686->proximity_dev = sensors_classdev_register("proximity_sensor");
	if (IS_ERR(cm36686->proximity_dev)) {
		pr_err("%s: could not create proximity_dev\n", __func__);
		goto err_proximity_device_create;
	}

	if (device_create_file(cm36686->proximity_dev, &dev_attr_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_state.attr.name);
		goto err_proximity_device_create_file1;
	}

	if (device_create_file(cm36686->proximity_dev, &attr_prox_raw) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			attr_prox_raw.attr.name);
		goto err_proximity_device_create_file2;
	}

#ifdef CM36686_CANCELATION
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_cal) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_cal.attr.name);
		goto err_proximity_device_create_file3;
	}
#endif
	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_prox_avg) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_prox_avg.attr.name);
		goto err_proximity_device_create_file4;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_high) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_high.attr.name);
		goto err_proximity_device_create_file5;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_proximity_device_create_file6;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_proximity_device_create_file7;
	}

	if (device_create_file(cm36686->proximity_dev,
		&dev_attr_thresh_low) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_thresh_low.attr.name);
		goto err_proximity_device_create_file8;
	}

	dev_set_drvdata(cm36686->proximity_dev, cm36686);

	/* set sysfs for light sensor */
	cm36686->light_dev = sensors_classdev_register("light_sensor");
	if (IS_ERR(cm36686->light_dev)) {
		pr_err("%s: could not create light_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_lux) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_lux.attr.name);
		goto err_light_device_create_file1;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_raw_data) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_raw_data.attr.name);
		goto err_light_device_create_file2;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_vendor) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_vendor.attr.name);
		goto err_light_device_create_file3;
	}

	if (device_create_file(cm36686->light_dev, &dev_attr_name) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_name.attr.name);
		goto err_light_device_create_file4;
	}

	dev_set_drvdata(cm36686->light_dev, cm36686);

	pr_info("%s is success.\n", __func__);
	goto done;

/* error, unwind it all */
err_light_device_create_file4:
	device_remove_file(cm36686->light_dev, &dev_attr_vendor);
err_light_device_create_file3:
	device_remove_file(cm36686->light_dev, &dev_attr_raw_data);
err_light_device_create_file2:
	device_remove_file(cm36686->light_dev, &dev_attr_lux);
err_light_device_create_file1:
	sensors_classdev_unregister(cm36686->light_dev);
err_light_device_create:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_low);
err_proximity_device_create_file8:
	device_remove_file(cm36686->proximity_dev, &dev_attr_name);
err_proximity_device_create_file7:
	device_remove_file(cm36686->proximity_dev, &dev_attr_vendor);
err_proximity_device_create_file6:
	device_remove_file(cm36686->proximity_dev, &dev_attr_thresh_high);
err_proximity_device_create_file5:
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_avg);
err_proximity_device_create_file4:
#ifdef CM36686_CANCELATION
	device_remove_file(cm36686->proximity_dev, &dev_attr_prox_cal);
err_proximity_device_create_file3:
#endif
	device_remove_file(cm36686->proximity_dev, &attr_prox_raw);
err_proximity_device_create_file2:
	device_remove_file(cm36686->proximity_dev, &dev_attr_state);
err_proximity_device_create_file1:
	sensors_classdev_unregister(cm36686->proximity_dev);
err_proximity_device_create:
	destroy_workqueue(cm36686->light_wq);
err_create_light_workqueue:
err_light_sensor_register_failed:
	sysfs_remove_group(&cm36686->light_input_dev->dev.kobj,
			   &light_attribute_group);
err_sysfs_create_group_light:
	input_unregister_device(cm36686->light_input_dev);
err_input_register_device_light:
err_input_allocate_device_light:
	destroy_workqueue(cm36686->prox_wq);
err_create_prox_workqueue:
	free_irq(cm36686->irq, cm36686);
	gpio_free(cm36686->pdata->irq);
err_setup_irq:
err_proximity_sensor_register_failed:
	sysfs_remove_group(&cm36686->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	input_unregister_device(cm36686->proximity_input_dev);
err_input_register_device_proximity:
err_input_allocate_device_proximity:
err_setup_reg:
	if (cm36686->pdata->cm36686_led_on)
		cm36686->pdata->cm36686_led_on(false);
	wake_lock_destroy(&cm36686->prx_wake_lock);
	mutex_destroy(&cm36686->read_lock);
	mutex_destroy(&cm36686->power_lock);
	kfree(cm36686);
done:
	return ret;
}
示例#18
0
static int msm_thermal_add_vdd_rstr_nodes(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *vdd_rstr_kobj = NULL;
	struct kobject *vdd_rstr_reg_kobj[MAX_RAILS] = {0};
	int rc = 0;
	int i = 0;

	if (!vdd_rstr_probed) {
		vdd_rstr_nodes_called = true;
		return rc;
	}

	if (vdd_rstr_probed && rails_cnt == 0)
		return rc;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		pr_err("%s: cannot find kobject for module %s\n",
			__func__, KBUILD_MODNAME);
		rc = -ENOENT;
		goto thermal_sysfs_add_exit;
	}

	vdd_rstr_kobj = kobject_create_and_add("vdd_restriction", module_kobj);
	if (!vdd_rstr_kobj) {
		pr_err("%s: cannot create vdd_restriction kobject\n", __func__);
		rc = -ENOMEM;
		goto thermal_sysfs_add_exit;
	}

	rc = sysfs_create_group(vdd_rstr_kobj, &vdd_rstr_en_attribs_gp);
	if (rc) {
		pr_err("%s: cannot create kobject attribute group\n", __func__);
		rc = -ENOMEM;
		goto thermal_sysfs_add_exit;
	}

	for (i = 0; i < rails_cnt; i++) {
		vdd_rstr_reg_kobj[i] = kobject_create_and_add(rails[i].name,
					vdd_rstr_kobj);
		if (!vdd_rstr_reg_kobj[i]) {
			pr_err("%s: cannot create for kobject for %s\n",
					__func__, rails[i].name);
			rc = -ENOMEM;
			goto thermal_sysfs_add_exit;
		}

		rails[i].attr_gp.attrs = kzalloc(sizeof(struct attribute *) * 3,
					GFP_KERNEL);
		if (!rails[i].attr_gp.attrs) {
			rc = -ENOMEM;
			goto thermal_sysfs_add_exit;
		}

		VDD_RES_RW_ATTRIB(rails[i], rails[i].level_attr, 0, level);
		VDD_RES_RO_ATTRIB(rails[i], rails[i].value_attr, 1, value);
		rails[i].attr_gp.attrs[2] = NULL;

		rc = sysfs_create_group(vdd_rstr_reg_kobj[i],
				&rails[i].attr_gp);
		if (rc) {
			pr_err("%s: cannot create attribute group for %s\n",
					__func__, rails[i].name);
			goto thermal_sysfs_add_exit;
		}
	}

	return rc;

thermal_sysfs_add_exit:
	if (rc) {
		for (i = 0; i < rails_cnt; i++) {
			kobject_del(vdd_rstr_reg_kobj[i]);
			kfree(rails[i].attr_gp.attrs);
		}
		if (vdd_rstr_kobj)
			kobject_del(vdd_rstr_kobj);
	}
	return rc;
}
示例#19
0
static int __init msi_init(void)
{
	int ret;

	if (acpi_disabled)
		return -ENODEV;

	if (force || dmi_check_system(msi_dmi_table))
		old_ec_model = 1;

	if (!old_ec_model)
		get_threeg_exists();

	if (!old_ec_model && dmi_check_system(msi_load_scm_models_dmi_table))
		load_scm_model = 1;

	if (auto_brightness < 0 || auto_brightness > 2)
		return -EINVAL;

	/* Register backlight stuff */

	if (acpi_video_backlight_support()) {
		pr_info("Brightness ignored, must be controlled by ACPI video driver\n");
	} else {
		struct backlight_properties props;
		memset(&props, 0, sizeof(struct backlight_properties));
		props.type = BACKLIGHT_PLATFORM;
		props.max_brightness = MSI_LCD_LEVEL_MAX - 1;
		msibl_device = backlight_device_register("msi-laptop-bl", NULL,
							 NULL, &msibl_ops,
							 &props);
		if (IS_ERR(msibl_device))
			return PTR_ERR(msibl_device);
	}

	ret = platform_driver_register(&msipf_driver);
	if (ret)
		goto fail_backlight;

	/* Register platform stuff */

	msipf_device = platform_device_alloc("msi-laptop-pf", -1);
	if (!msipf_device) {
		ret = -ENOMEM;
		goto fail_platform_driver;
	}

	ret = platform_device_add(msipf_device);
	if (ret)
		goto fail_platform_device1;

	if (load_scm_model && (load_scm_model_init(msipf_device) < 0)) {
		ret = -EINVAL;
		goto fail_platform_device1;
	}

	ret = sysfs_create_group(&msipf_device->dev.kobj,
				 &msipf_attribute_group);
	if (ret)
		goto fail_platform_device2;

	if (!old_ec_model) {
		if (threeg_exists)
			ret = device_create_file(&msipf_device->dev,
						&dev_attr_threeg);
		if (ret)
			goto fail_platform_device2;
	}

	/* Disable automatic brightness control by default because
	 * this module was probably loaded to do brightness control in
	 * software. */

	if (auto_brightness != 2)
		set_auto_brightness(auto_brightness);

	pr_info("driver " MSI_DRIVER_VERSION " successfully loaded\n");

	return 0;

fail_platform_device2:

	if (load_scm_model) {
		i8042_remove_filter(msi_laptop_i8042_filter);
		cancel_delayed_work_sync(&msi_rfkill_work);
		rfkill_cleanup();
	}
	platform_device_del(msipf_device);

fail_platform_device1:

	platform_device_put(msipf_device);

fail_platform_driver:

	platform_driver_unregister(&msipf_driver);

fail_backlight:

	backlight_device_unregister(msibl_device);

	return ret;
}
示例#20
0
static int msm_thermal_add_psm_nodes(void)
{
	struct kobject *module_kobj = NULL;
	struct kobject *psm_kobj = NULL;
	struct kobject *psm_reg_kobj[MAX_RAILS] = {0};
	int rc = 0;
	int i = 0;

	if (!psm_probed) {
		psm_nodes_called = true;
		return rc;
	}

	if (psm_probed && psm_rails_cnt == 0)
		return rc;

	module_kobj = kset_find_obj(module_kset, KBUILD_MODNAME);
	if (!module_kobj) {
		pr_err("%s: cannot find kobject for module %s\n",
			__func__, KBUILD_MODNAME);
		rc = -ENOENT;
		goto psm_node_exit;
	}

	psm_kobj = kobject_create_and_add("pmic_sw_mode", module_kobj);
	if (!psm_kobj) {
		pr_err("%s: cannot create psm kobject\n", KBUILD_MODNAME);
		rc = -ENOMEM;
		goto psm_node_exit;
	}

	for (i = 0; i < psm_rails_cnt; i++) {
		psm_reg_kobj[i] = kobject_create_and_add(psm_rails[i].name,
					psm_kobj);
		if (!psm_reg_kobj[i]) {
			pr_err("%s: cannot create for kobject for %s\n",
					KBUILD_MODNAME, psm_rails[i].name);
			rc = -ENOMEM;
			goto psm_node_exit;
		}
		psm_rails[i].attr_gp.attrs = kzalloc( \
				sizeof(struct attribute *) * 2, GFP_KERNEL);
		if (!psm_rails[i].attr_gp.attrs) {
			rc = -ENOMEM;
			goto psm_node_exit;
		}

		PSM_RW_ATTRIB(psm_rails[i], psm_rails[i].mode_attr, 0, mode);
		psm_rails[i].attr_gp.attrs[1] = NULL;

		rc = sysfs_create_group(psm_reg_kobj[i], &psm_rails[i].attr_gp);
		if (rc) {
			pr_err("%s: cannot create attribute group for %s\n",
					KBUILD_MODNAME, psm_rails[i].name);
			goto psm_node_exit;
		}
	}

	return rc;

psm_node_exit:
	if (rc) {
		for (i = 0; i < psm_rails_cnt; i++) {
			kobject_del(psm_reg_kobj[i]);
			kfree(psm_rails[i].attr_gp.attrs);
		}
		if (psm_kobj)
			kobject_del(psm_kobj);
	}
	return rc;
}
示例#21
0
static int
lightsensor_probe(struct platform_device *pdev)
{
	struct sensor_data *data = NULL;
	struct input_dev *input_data = NULL;
	int input_registered = 0, sysfs_created = 0;
	int rt;

	data = kzalloc(sizeof(struct sensor_data), GFP_KERNEL);
	if (!data) {
		rt = -ENOMEM;
		goto err;
	}
	data->enabled = 0;
	data->delay = SENSOR_DEFAULT_DELAY;
	data->testmode = 0;
	data->light_level_state =0;

	light_workqueue = create_singlethread_workqueue("klightd");
	if (!light_workqueue) {
		rt = -ENOMEM;
		printk(KERN_ERR "%s: Failed to allocate work queue\n", __func__);
		goto err;
	}

	INIT_DELAYED_WORK(&data->work, gp2a_work_func_light);

	input_data = input_allocate_device();
	if (!input_data) {
		rt = -ENOMEM;
		printk(KERN_ERR
			"sensor_probe: Failed to allocate input_data device\n");
		goto err;
	}

	set_bit(EV_ABS, input_data->evbit);
	input_set_capability(input_data, EV_ABS, ABS_X);
	input_set_capability(input_data, EV_ABS, ABS_MISC);
	input_set_capability(input_data, EV_ABS, ABS_WAKE); /* wake */
	input_set_capability(input_data, EV_ABS, ABS_CONTROL_REPORT); /* enabled/delay */
	input_data->name = SENSOR_NAME;

	rt = input_register_device(input_data);
	if (rt) {
		printk(KERN_ERR
			"sensor_probe: Unable to register input_data device: %s\n",
			input_data->name);
		goto err;
	}
	input_set_drvdata(input_data, data);
	input_registered = 1;

	rt = sysfs_create_group(&input_data->dev.kobj,
				&lightsensor_attribute_group);
	if (rt) {
		printk(KERN_ERR
			"sensor_probe: sysfs_create_group failed[%s]\n",
			input_data->name);
		goto err;
	}
	sysfs_created = 1;
	mutex_init(&data->mutex);
	this_data = input_data;

#if 0 //def MSM_LIGHTSENSOR_ADC_READ  
	lightsensor_rpc_init();
#endif

	data->lightsensor_class = class_create(THIS_MODULE, "lightsensor");
	if (IS_ERR(data->lightsensor_class)) {
		pr_err("%s: could not create lightsensor_class\n", __func__);
		goto err;
	}

	data->switch_cmd_dev = device_create(data->lightsensor_class,
						NULL, 0, NULL, "switch_cmd");
	if (IS_ERR(data->switch_cmd_dev)) {
		pr_err("%s: could not create switch_cmd_dev\n", __func__);
		goto err_light_device_create;
	}

	if (device_create_file(data->switch_cmd_dev,
		&dev_attr_lightsensor_file_state) < 0) {
		pr_err("%s: could not create device file(%s)!\n", __func__,
			dev_attr_lightsensor_file_state.attr.name);
		goto err_light_device_create_file;
	}
	dev_set_drvdata(data->switch_cmd_dev, data);
	return 0;

err_light_device_create_file:
	device_destroy(data->lightsensor_class, 0);
err_light_device_create:
	class_destroy(data->lightsensor_class);
err:
	if (data != NULL) {
		if (input_data != NULL) {
			if (sysfs_created) {
				sysfs_remove_group(&input_data->dev.kobj,
						&lightsensor_attribute_group);
			}
			if (input_registered)
				input_unregister_device(input_data);
			else
				input_free_device(input_data);
			input_data = NULL;
		}
		kfree(data);
	}

	return rt;
}
static int gp2a_i2c_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	int ret = -ENODEV;
	struct input_dev *input_dev;
	struct gp2a_data *gp2a;
	struct gp2a_platform_data *pdata = client->dev.platform_data;
	pr_info("[TMP] %s, %d\n", __func__, __LINE__);

	nondetect = PROX_NONDETECT;
	detect = PROX_DETECT;
/*#else
	if (board_hw_revision >= 0x07) {
		nondetect = PROX_REV_07_NONDETECT;
		detect = PROX_REV_07_DETECT;
	} else {
		nondetect = PROX_REV_06_NONDETECT;
		detect = PROX_REV_06_DETECT;
	}
#endif*/
	pr_info("%s: %02x %02x\n", __func__, nondetect, detect);
	if (!pdata) {
		pr_err("%s: missing pdata!\n", __func__);
		return ret;
	}

	if (!pdata->power) {
		pr_err("%s: incomplete pdata!\n", __func__);
		return ret;
	}

	/* power on gp2a */
	pdata->power(true);

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		pr_err("%s: i2c functionality check failed!\n", __func__);
		return ret;
	}

	gp2a = kzalloc(sizeof(struct gp2a_data), GFP_KERNEL);
	if (!gp2a) {
		pr_err("%s: failed to alloc memory for module data\n",
		       __func__);
		return -ENOMEM;
	}

	gp2a->pdata = pdata;
	gp2a->i2c_client = client;
	i2c_set_clientdata(client, gp2a);

	/* wake lock init */
	wake_lock_init(&gp2a->prx_wake_lock, WAKE_LOCK_SUSPEND,
		       "prx_wake_lock");
	mutex_init(&gp2a->power_lock);

	/* allocate proximity input_device */
	input_dev = input_allocate_device();
	if (!input_dev) {
		pr_err("%s: could not allocate input device\n", __func__);
		goto err_input_allocate_device_proximity;
	}
	input_dev->name = "proximity_sensor";
	ret = input_register_device(input_dev);
	if (ret < 0) {
		pr_err("%s: could not register input device\n",
			__func__);
		input_free_device(input_dev);
		goto err_input_allocate_device_proximity;
	}

	gp2a->proximity_input_dev = input_dev;
	input_set_drvdata(input_dev, gp2a);
	input_set_capability(input_dev, EV_ABS, ABS_DISTANCE);
	input_set_abs_params(input_dev, ABS_DISTANCE, 0, 1, 0, 0);

	ret = sysfs_create_group(&input_dev->dev.kobj,
				 &proximity_attribute_group);

	if (ret) {
		pr_err("%s: could not create sysfs group\n", __func__);
		goto err_sysfs_create_group_proximity;
	}

	/* the timer just fires off a work queue request.  we need a thread
	   to read the i2c (can be slow and blocking). */
	INIT_WORK(&gp2a->work_prox, gp2a_prox_work_func);
	ret = gp2a_setup_irq(gp2a);

	if (ret) {
		pr_err("%s: could not setup irq\n", __func__);
		goto err_setup_irq;
	}

	ret = sensors_register(gp2a->proximity_dev, gp2a,
		proxi_attrs, "proximity_sensor");
	if (ret < 0) {
		pr_info("%s: could not sensors_register\n", __func__);
		goto exit_gp2a_sensors_register;
	}

#ifdef CONFIG_SENSOR_USE_SYMLINK
	ret =  sensors_initialize_symlink(gp2a->proximity_input_dev);
	if (ret) {
		pr_err("%s: cound not make proximity sensor symlink(%d).\n",
			__func__, ret);
		goto exit_sensors_initialize_symlink;
	}
#endif

	/* set initial proximity value as 1 */
	input_report_abs(gp2a->proximity_input_dev, ABS_DISTANCE, 1);
	input_sync(gp2a->proximity_input_dev);

	pr_info("[TMP] %s, %d\n", __func__, __LINE__);

	pdata->power(false);
	goto done;

	/* error, unwind it all */
#ifdef CONFIG_SENSOR_USE_SYMLINK
exit_sensors_initialize_symlink:
#endif
exit_gp2a_sensors_register:
	free_irq(gp2a->irq, gp2a);
	gpio_free(gp2a->pdata->p_out);
err_setup_irq:
	pr_info("err_setup_irq\n");
	sysfs_remove_group(&gp2a->proximity_input_dev->dev.kobj,
			   &proximity_attribute_group);
err_sysfs_create_group_proximity:
	pr_info("err_sysfs_create_group_proximity\n");
	input_unregister_device(gp2a->proximity_input_dev);
err_input_allocate_device_proximity:
	pr_info("err_input_allocate_device_proximity\n");
	mutex_destroy(&gp2a->power_lock);
	wake_lock_destroy(&gp2a->prx_wake_lock);
	kfree(gp2a);
done:
	pr_info("done\n");
	return ret;
}
示例#23
0
static int tpo_td043_probe(struct spi_device *spi)
{
	struct panel_drv_data *ddata;
	struct omap_dss_device *dssdev;
	int r;

	dev_dbg(&spi->dev, "%s\n", __func__);

	spi->bits_per_word = 16;
	spi->mode = SPI_MODE_0;

	r = spi_setup(spi);
	if (r < 0) {
		dev_err(&spi->dev, "spi_setup failed: %d\n", r);
		return r;
	}

	ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
	if (ddata == NULL)
		return -ENOMEM;

	dev_set_drvdata(&spi->dev, ddata);

	ddata->spi = spi;

	if (!spi->dev.of_node)
		return -ENODEV;

	r = tpo_td043_probe_of(spi);
	if (r)
		return r;

	ddata->mode = TPO_R02_MODE_800x480;
	memcpy(ddata->gamma, tpo_td043_def_gamma, sizeof(ddata->gamma));

	ddata->vcc_reg = devm_regulator_get(&spi->dev, "vcc");
	if (IS_ERR(ddata->vcc_reg)) {
		dev_err(&spi->dev, "failed to get LCD VCC regulator\n");
		r = PTR_ERR(ddata->vcc_reg);
		goto err_regulator;
	}

	if (gpio_is_valid(ddata->nreset_gpio)) {
		r = devm_gpio_request_one(&spi->dev,
				ddata->nreset_gpio, GPIOF_OUT_INIT_LOW,
				"lcd reset");
		if (r < 0) {
			dev_err(&spi->dev, "couldn't request reset GPIO\n");
			goto err_gpio_req;
		}
	}

	r = sysfs_create_group(&spi->dev.kobj, &tpo_td043_attr_group);
	if (r) {
		dev_err(&spi->dev, "failed to create sysfs files\n");
		goto err_sysfs;
	}

	ddata->videomode = tpo_td043_timings;

	dssdev = &ddata->dssdev;
	dssdev->dev = &spi->dev;
	dssdev->driver = &tpo_td043_ops;
	dssdev->type = OMAP_DISPLAY_TYPE_DPI;
	dssdev->owner = THIS_MODULE;
	dssdev->panel.timings = ddata->videomode;

	r = omapdss_register_display(dssdev);
	if (r) {
		dev_err(&spi->dev, "Failed to register panel\n");
		goto err_reg;
	}

	return 0;

err_reg:
	sysfs_remove_group(&spi->dev.kobj, &tpo_td043_attr_group);
err_sysfs:
err_gpio_req:
err_regulator:
	omap_dss_put_device(ddata->in);
	return r;
}
示例#24
0
static int __init brcmstb_gisb_arb_probe(struct platform_device *pdev)
{
	struct device_node *dn = pdev->dev.of_node;
	struct brcmstb_gisb_arb_device *gdev;
	const struct of_device_id *of_id;
	struct resource *r;
	int err, timeout_irq, tea_irq;
	unsigned int num_masters, j = 0;
	int i, first, last;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	timeout_irq = platform_get_irq(pdev, 0);
	tea_irq = platform_get_irq(pdev, 1);

	gdev = devm_kzalloc(&pdev->dev, sizeof(*gdev), GFP_KERNEL);
	if (!gdev)
		return -ENOMEM;

	mutex_init(&gdev->lock);
	INIT_LIST_HEAD(&gdev->next);

	gdev->base = devm_ioremap_resource(&pdev->dev, r);
	if (IS_ERR(gdev->base))
		return PTR_ERR(gdev->base);

	of_id = of_match_node(brcmstb_gisb_arb_of_match, dn);
	if (!of_id) {
		pr_err("failed to look up compatible string\n");
		return -EINVAL;
	}
	gdev->gisb_offsets = of_id->data;
	gdev->big_endian = of_device_is_big_endian(dn);

	err = devm_request_irq(&pdev->dev, timeout_irq,
				brcmstb_gisb_timeout_handler, 0, pdev->name,
				gdev);
	if (err < 0)
		return err;

	err = devm_request_irq(&pdev->dev, tea_irq,
				brcmstb_gisb_tea_handler, 0, pdev->name,
				gdev);
	if (err < 0)
		return err;

	/* If we do not have a valid mask, assume all masters are enabled */
	if (of_property_read_u32(dn, "brcm,gisb-arb-master-mask",
				&gdev->valid_mask))
		gdev->valid_mask = 0xffffffff;

	/* Proceed with reading the litteral names if we agree on the
	 * number of masters
	 */
	num_masters = of_property_count_strings(dn,
			"brcm,gisb-arb-master-names");
	if (hweight_long(gdev->valid_mask) == num_masters) {
		first = ffs(gdev->valid_mask) - 1;
		last = fls(gdev->valid_mask) - 1;

		for (i = first; i < last; i++) {
			if (!(gdev->valid_mask & BIT(i)))
				continue;

			of_property_read_string_index(dn,
					"brcm,gisb-arb-master-names", j,
					&gdev->master_names[i]);
			j++;
		}
	}

	err = sysfs_create_group(&pdev->dev.kobj, &gisb_arb_sysfs_attr_group);
	if (err)
		return err;

	platform_set_drvdata(pdev, gdev);

	list_add_tail(&gdev->next, &brcmstb_gisb_arb_device_list);

#ifdef CONFIG_ARM
	hook_fault_code(22, brcmstb_bus_error_handler, SIGBUS, 0,
			"imprecise external abort");
#endif

	dev_info(&pdev->dev, "registered mem: %p, irqs: %d, %d\n",
			gdev->base, timeout_irq, tea_irq);

	return 0;
}
示例#25
0
static int __devinit ab8500_temp_probe(struct platform_device *pdev)
{
	struct ab8500_temp *data;
	int err;

	data = kzalloc(sizeof(struct ab8500_temp), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->gpadc = ab8500_gpadc_get();

	data->hwmon_dev = hwmon_device_register(&pdev->dev);
	if (IS_ERR(data->hwmon_dev)) {
		err = PTR_ERR(data->hwmon_dev);
		dev_err(&pdev->dev, "Class registration failed (%d)\n", err);
		goto exit;
	}

	INIT_DELAYED_WORK_DEFERRABLE(&data->work, gpadc_monitor);
	INIT_DELAYED_WORK(&data->power_off_work, thermal_power_off);

	/*
	 * Setup HW defined data.
	 *
	 * Reference hardware (HREF):
	 *
	 * GPADC - ADC_AUX1, connected to NTC R2148 next to RTC_XTAL on HREF
	 * GPADC - ADC_AUX2, connected to NTC R2150 near DB8500 on HREF
	 * Hence, temp#_min/max/max_hyst refer to millivolts and not
	 * millidegrees
	 *
	 * HREF HW does not support reading AB8500 temperature. BUT an
	 * AB8500 IRQ will be launched if die crit temp limit is reached.
	 *
	 * Also:
	 * Battery temperature (BatTemp and BatCtrl) thresholds will
	 * not be exposed via hwmon.
	 *
	 * Make sure indexes correspond to the attribute indexes
	 * used when calling SENSOR_DEVICE_ATRR
	 */
	data->gpadc_addr[0] = ADC_AUX1;
	data->gpadc_addr[1] = ADC_AUX2;
	data->gpadc_addr[2] = BTEMP_BALL;
	data->gpadc_addr[4] = BAT_CTRL;
	mutex_init(&data->lock);
	data->pdev = pdev;
	data->power_off_delay = DEFAULT_POWER_OFF_DELAY;

	platform_set_drvdata(pdev, data);

	err = sysfs_create_group(&pdev->dev.kobj, &ab8500_temp_group);
	if (err < 0) {
		dev_err(&pdev->dev, "Create sysfs group failed (%d)\n", err);
		goto exit_platform_data;
	}

	err = setup_irqs(pdev);
	if (err < 0)
		goto exit_platform_data;

	return 0;

exit_platform_data:
	platform_set_drvdata(pdev, NULL);
exit:
	kfree(data);
	return err;
}
示例#26
0
static int acx565akm_probe(struct spi_device *spi)
{
	struct panel_drv_data *ddata;
	struct omap_dss_device *dssdev;
	struct backlight_device *bldev;
	int max_brightness, brightness;
	struct backlight_properties props;
	int r;

	dev_dbg(&spi->dev, "%s\n", __func__);

	spi->mode = SPI_MODE_3;

	ddata = devm_kzalloc(&spi->dev, sizeof(*ddata), GFP_KERNEL);
	if (ddata == NULL)
		return -ENOMEM;

	dev_set_drvdata(&spi->dev, ddata);

	ddata->spi = spi;

	mutex_init(&ddata->mutex);

	if (dev_get_platdata(&spi->dev)) {
		r = acx565akm_probe_pdata(spi);
		if (r)
			return r;
	} else if (spi->dev.of_node) {
		r = acx565akm_probe_of(spi);
		if (r)
			return r;
	} else {
		dev_err(&spi->dev, "platform data missing!\n");
		return -ENODEV;
	}

	if (gpio_is_valid(ddata->reset_gpio)) {
		r = devm_gpio_request_one(&spi->dev, ddata->reset_gpio,
				GPIOF_OUT_INIT_LOW, "lcd reset");
		if (r)
			goto err_gpio;
	}

	if (gpio_is_valid(ddata->reset_gpio))
		gpio_set_value(ddata->reset_gpio, 1);

	/*
	 * After reset we have to wait 5 msec before the first
	 * command can be sent.
	 */
	usleep_range(5000, 10000);

	ddata->enabled = panel_enabled(ddata);

	r = panel_detect(ddata);

	if (!ddata->enabled && gpio_is_valid(ddata->reset_gpio))
		gpio_set_value(ddata->reset_gpio, 0);

	if (r) {
		dev_err(&spi->dev, "%s panel detect error\n", __func__);
		goto err_detect;
	}

	memset(&props, 0, sizeof(props));
	props.fb_blank = FB_BLANK_UNBLANK;
	props.power = FB_BLANK_UNBLANK;
	props.type = BACKLIGHT_RAW;

	bldev = backlight_device_register("acx565akm", &ddata->spi->dev,
			ddata, &acx565akm_bl_ops, &props);
	if (IS_ERR(bldev)) {
		r = PTR_ERR(bldev);
		goto err_reg_bl;
	}
	ddata->bl_dev = bldev;
	if (ddata->has_cabc) {
		r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
		if (r) {
			dev_err(&bldev->dev,
				"%s failed to create sysfs files\n", __func__);
			goto err_sysfs;
		}
		ddata->cabc_mode = get_hw_cabc_mode(ddata);
	}

	max_brightness = 255;

	if (ddata->has_bc)
		brightness = acx565akm_get_actual_brightness(ddata);
	else
		brightness = 0;

	bldev->props.max_brightness = max_brightness;
	bldev->props.brightness = brightness;

	acx565akm_bl_update_status(bldev);


	ddata->videomode = acx565akm_panel_timings;

	dssdev = &ddata->dssdev;
	dssdev->dev = &spi->dev;
	dssdev->driver = &acx565akm_ops;
	dssdev->type = OMAP_DISPLAY_TYPE_SDI;
	dssdev->owner = THIS_MODULE;
	dssdev->panel.timings = ddata->videomode;

	r = omapdss_register_display(dssdev);
	if (r) {
		dev_err(&spi->dev, "Failed to register panel\n");
		goto err_reg;
	}

	return 0;

err_reg:
	sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group);
err_sysfs:
	backlight_device_unregister(bldev);
err_reg_bl:
err_detect:
err_gpio:
	omap_dss_put_device(ddata->in);
	return r;
}
示例#27
0
int mdp3_ctrl_init(struct msm_fb_data_type *mfd)
{
	struct device *dev = mfd->fbi->dev;
	struct msm_mdp_interface *mdp3_interface = &mfd->mdp;
	struct mdp3_session_data *mdp3_session = NULL;
	u32 intf_type = MDP3_DMA_OUTPUT_SEL_DSI_VIDEO;
	int rc;
	int splash_mismatch = 0;

	pr_debug("mdp3_ctrl_init\n");
	rc = mdp3_parse_dt_splash(mfd);
	if (rc)
		splash_mismatch = 1;

	mdp3_interface->on_fnc = mdp3_ctrl_on;
	mdp3_interface->off_fnc = mdp3_ctrl_off;
	mdp3_interface->do_histogram = NULL;
	mdp3_interface->cursor_update = NULL;
	mdp3_interface->dma_fnc = mdp3_ctrl_pan_display;
	mdp3_interface->ioctl_handler = mdp3_ctrl_ioctl_handler;
	mdp3_interface->kickoff_fnc = mdp3_ctrl_display_commit_kickoff;
	mdp3_interface->lut_update = mdp3_ctrl_lut_update;

	mdp3_session = kmalloc(sizeof(struct mdp3_session_data), GFP_KERNEL);
	if (!mdp3_session) {
		pr_err("fail to allocate mdp3 private data structure");
		return -ENOMEM;
	}
	memset(mdp3_session, 0, sizeof(struct mdp3_session_data));
	mutex_init(&mdp3_session->lock);
	INIT_WORK(&mdp3_session->clk_off_work, mdp3_dispatch_clk_off);
	atomic_set(&mdp3_session->vsync_countdown, 0);
	mutex_init(&mdp3_session->histo_lock);
	mdp3_session->dma = mdp3_get_dma_pipe(MDP3_DMA_CAP_ALL);
	if (!mdp3_session->dma) {
		rc = -ENODEV;
		goto init_done;
	}

	rc = mdp3_dma_init(mdp3_session->dma);
	if (rc) {
		pr_err("fail to init dma\n");
		goto init_done;
	}

	intf_type = mdp3_ctrl_get_intf_type(mfd);
	mdp3_session->intf = mdp3_get_display_intf(intf_type);
	if (!mdp3_session->intf) {
		rc = -ENODEV;
		goto init_done;
	}
	rc = mdp3_intf_init(mdp3_session->intf);
	if (rc) {
		pr_err("fail to init interface\n");
		goto init_done;
	}

	mdp3_session->dma->output_config.out_sel = intf_type;
	mdp3_session->mfd = mfd;
	mdp3_session->panel = dev_get_platdata(&mfd->pdev->dev);
	mdp3_session->status = mdp3_session->intf->active;
	mdp3_session->overlay.id = MSMFB_NEW_REQUEST;
	mdp3_bufq_init(&mdp3_session->bufq_in);
	mdp3_bufq_init(&mdp3_session->bufq_out);
	mdp3_session->histo_status = 0;
	mdp3_session->lut_sel = 0;

	init_timer(&mdp3_session->vsync_timer);
	mdp3_session->vsync_timer.function = mdp3_vsync_timer_func;
	mdp3_session->vsync_timer.data = (u32)mdp3_session;
	mdp3_session->vsync_period = 1000 / mfd->panel_info->mipi.frame_rate;
	mfd->mdp.private1 = mdp3_session;

	rc = sysfs_create_group(&dev->kobj, &vsync_fs_attr_group);
	if (rc) {
		pr_err("vsync sysfs group creation failed, ret=%d\n", rc);
		goto init_done;
	}

	mdp3_session->vsync_event_sd = sysfs_get_dirent(dev->kobj.sd, NULL,
							"vsync_event");
	if (!mdp3_session->vsync_event_sd) {
		pr_err("vsync_event sysfs lookup failed\n");
		rc = -ENODEV;
		goto init_done;
	}

	rc = mdp3_create_sysfs_link(dev);
	if (rc)
		pr_warn("problem creating link to mdp sysfs\n");

	kobject_uevent(&dev->kobj, KOBJ_ADD);
	pr_debug("vsync kobject_uevent(KOBJ_ADD)\n");

	if (splash_mismatch) {
		pr_err("splash memory mismatch, stop splash\n");
		mdp3_ctrl_off(mfd);
	}

	if (mdp3_get_cont_spash_en())
		mdp3_session->clk_on = 1;

	mdp3_session->vsync_before_commit = true;
init_done:
	if (IS_ERR_VALUE(rc))
		kfree(mdp3_session);

	return rc;
}
static int __init smba1002_gsm_probe(struct platform_device *pdev)
{
	struct rfkill *rfkill;
	struct regulator *regulator[2];
	struct smba1002_pm_gsm_data *gsm_data;
	int ret;

	gsm_data = kzalloc(sizeof(*gsm_data), GFP_KERNEL);
	if (!gsm_data) {
		dev_err(&pdev->dev, "no memory for context\n");
		return -ENOMEM;
	}
	dev_set_drvdata(&pdev->dev, gsm_data);

	regulator[0] = regulator_get(&pdev->dev, "avdd_usb_pll");
	if (IS_ERR(regulator[0])) {
		dev_err(&pdev->dev, "unable to get regulator for usb pll\n");
		kfree(gsm_data);
		dev_set_drvdata(&pdev->dev, NULL);
		return -ENODEV;
	}
	gsm_data->regulator[0] = regulator[0];

	regulator[1] = regulator_get(&pdev->dev, "avdd_usb");
	if (IS_ERR(regulator[1])) {
		dev_err(&pdev->dev, "unable to get regulator for usb\n");
		regulator_put(regulator[0]);
		gsm_data->regulator[0] = NULL;
		kfree(gsm_data);
		dev_set_drvdata(&pdev->dev, NULL);
		return -ENODEV;
	}
	gsm_data->regulator[1] = regulator[1];
	
	/* Init control pins */
	gpio_request(SMBA1002_3G_DISABLE, "gsm_disable");
	gpio_direction_output(SMBA1002_3G_DISABLE, 1);
//	smba1002_3g_gps_init();

	/* register rfkill interface */
	rfkill = rfkill_alloc(pdev->name, &pdev->dev, RFKILL_TYPE_WWAN,
                            &smba1002_gsm_rfkill_ops, &pdev->dev);

	if (!rfkill) {
		dev_err(&pdev->dev, "Failed to allocate rfkill\n");
		regulator_put(regulator[1]);
		gsm_data->regulator[1] = NULL;
		regulator_put(regulator[0]);
		gsm_data->regulator[0] = NULL;
		kfree(gsm_data);
		dev_set_drvdata(&pdev->dev, NULL);
		return -ENOMEM;
	}
	gsm_data->rfkill = rfkill;

	/* Disable bluetooth */
    rfkill_init_sw_state(rfkill, 0);

	ret = rfkill_register(rfkill);
	if (ret) {
		rfkill_destroy(rfkill);
		dev_err(&pdev->dev, "Failed to register rfkill\n");
		return ret;
	}

	dev_info(&pdev->dev, "GSM/UMTS RFKill driver loaded\n");
	
	return sysfs_create_group(&pdev->dev.kobj, &smba1002_gsm_attr_group);
}
int mdp4_dsi_video_on(struct platform_device *pdev)
{
	int dsi_width;
	int dsi_height;
	int dsi_bpp;
	int dsi_border_clr;
	int dsi_underflow_clr;
	int dsi_hsync_skew;

	int hsync_period;
	int hsync_ctrl;
	int vsync_period;
	int display_hctl;
	int display_v_start;
	int display_v_end;
	int active_hctl;
	int active_h_start;
	int active_h_end;
	int active_v_start;
	int active_v_end;
	int ctrl_polarity;
	int h_back_porch;
	int h_front_porch;
	int v_back_porch;
	int v_front_porch;
	int hsync_pulse_width;
	int vsync_pulse_width;
	int hsync_polarity;
	int vsync_polarity;
	int data_en_polarity;
	int hsync_start_x;
	int hsync_end_x;
	uint8 *buf;
	unsigned int buf_offset;
	int bpp, ptype;
	static bool first_video_on = true;
	struct fb_info *fbi;
	struct fb_var_screeninfo *var;
	struct msm_fb_data_type *mfd;
	struct mdp4_overlay_pipe *pipe;
	int ret = 0;
	int cndx = 0;
	struct vsycn_ctrl *vctrl;

	vctrl = &vsync_ctrl_db[cndx];
	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);

	if (!mfd)
		return -ENODEV;

	if (mfd->key != MFD_KEY)
		return -EINVAL;

	vctrl->mfd = mfd;
	vctrl->dev = mfd->fbi->dev;

	
	mdp_clk_ctrl(1);

	fbi = mfd->fbi;
	var = &fbi->var;

	bpp = fbi->var.bits_per_pixel / 8;
	buf = (uint8 *) fbi->fix.smem_start;
	buf_offset = calc_fb_offset(mfd, fbi, bpp);

	if (first_video_on)
		first_video_on = false;
	else {
		if (mfd->ref_cnt == 0) {
			
			int ndx;
			for (ndx=1; ndx<4; ndx++) {
				pipe = mdp4_overlay_ndx2pipe(ndx);
				if (pipe && pipe->pipe_used)
					mdp4_overlay_unset(mfd->fbi, ndx);
			}
		}
	}

	if (vctrl->base_pipe == NULL) {
		ptype = mdp4_overlay_format2type(mfd->fb_imgType);
		if (ptype < 0)
			printk(KERN_INFO "%s: format2type failed\n", __func__);
		pipe = mdp4_overlay_pipe_alloc(ptype, MDP4_MIXER0);
		if (pipe == NULL) {
			printk(KERN_INFO "%s: pipe_alloc failed\n", __func__);
			return -EBUSY;
		}
		pipe->pipe_used++;
		pipe->mixer_stage  = MDP4_MIXER_STAGE_BASE;
		pipe->mixer_num  = MDP4_MIXER0;
		pipe->src_format = mfd->fb_imgType;
		mdp4_overlay_panel_mode(pipe->mixer_num, MDP4_PANEL_DSI_VIDEO);
		ret = mdp4_overlay_format2pipe(pipe);
		if (ret < 0)
			printk(KERN_INFO "%s: format2type failed\n", __func__);

		pipe->ov_blt_addr = 0;
		pipe->dma_blt_addr = 0;
		vctrl->base_pipe = pipe; 
		mdp4_init_writeback_buf(mfd, MDP4_MIXER0);

	} else {
		pipe = vctrl->base_pipe;
	}

#ifdef CONTINUOUS_SPLASH
	
	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);

	if (!(mfd->cont_splash_done)) {
		mfd->cont_splash_done = 1;
		mdp4_dsi_video_wait4dmap_done(0);
		MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE, 0);
		mdelay(20);
		mipi_dsi_controller_cfg(0);
		mfd->cont_splash_done = 1;
		mdp_clk_ctrl(0);
	}
#endif

	pipe->src_height = fbi->var.yres;
	pipe->src_width = fbi->var.xres;
	pipe->src_h = fbi->var.yres;
	pipe->src_w = fbi->var.xres;
	pipe->src_y = 0;
	pipe->src_x = 0;
	pipe->dst_h = fbi->var.yres;
	pipe->dst_w = fbi->var.xres;
	pipe->srcp0_ystride = fbi->fix.line_length;
	pipe->bpp = bpp;

	if (mfd->display_iova)
		pipe->srcp0_addr = mfd->display_iova + buf_offset;
	else
		pipe->srcp0_addr = (uint32)(buf + buf_offset);

	pipe->dst_h = fbi->var.yres;
	pipe->dst_w = fbi->var.xres;

	mdp4_overlay_mdp_pipe_req(pipe, mfd);

	atomic_set(&vctrl->suspend, 0);

	mdp4_overlay_dmap_xy(pipe);	
	mdp4_overlay_dmap_cfg(mfd, 1);
	mdp4_overlay_rgb_setup(pipe);
	mdp4_overlayproc_cfg(pipe);

	mdp4_overlay_reg_flush(pipe, 1);

	mdp4_mixer_stage_up(pipe, 0);
	mdp4_mixer_stage_commit(pipe->mixer_num);

	h_back_porch = var->left_margin;
	h_front_porch = var->right_margin;
	v_back_porch = var->upper_margin;
	v_front_porch = var->lower_margin;
	hsync_pulse_width = var->hsync_len;
	vsync_pulse_width = var->vsync_len;
	dsi_border_clr = mfd->panel_info.lcdc.border_clr;
	dsi_underflow_clr = mfd->panel_info.lcdc.underflow_clr;
	dsi_hsync_skew = mfd->panel_info.lcdc.hsync_skew;
	dsi_width = mfd->panel_info.xres +
		mfd->panel_info.lcdc.xres_pad;
	dsi_height = mfd->panel_info.yres +
		mfd->panel_info.lcdc.yres_pad;
	dsi_bpp = mfd->panel_info.bpp;

	hsync_period = hsync_pulse_width + h_back_porch + dsi_width
				+ h_front_porch;
	hsync_ctrl = (hsync_period << 16) | hsync_pulse_width;
	hsync_start_x = h_back_porch + hsync_pulse_width;
	hsync_end_x = hsync_period - h_front_porch - 1;
	display_hctl = (hsync_end_x << 16) | hsync_start_x;

	vsync_period =
	    (vsync_pulse_width + v_back_porch + dsi_height + v_front_porch);
	display_v_start = ((vsync_pulse_width + v_back_porch) * hsync_period)
				+ dsi_hsync_skew;
	display_v_end =
	  ((vsync_period - v_front_porch) * hsync_period) + dsi_hsync_skew - 1;

	if (dsi_width != var->xres) {
		active_h_start = hsync_start_x + first_pixel_start_x;
		active_h_end = active_h_start + var->xres - 1;
		active_hctl =
		    ACTIVE_START_X_EN | (active_h_end << 16) | active_h_start;
	} else {
		active_hctl = 0;
	}

	if (dsi_height != var->yres) {
		active_v_start =
		    display_v_start + first_pixel_start_y * hsync_period;
		active_v_end = active_v_start + (var->yres) * hsync_period - 1;
		active_v_start |= ACTIVE_START_Y_EN;
	} else {
		active_v_start = 0;
		active_v_end = 0;
	}

	dsi_underflow_clr |= 0x80000000;	
	hsync_polarity = 0;
	vsync_polarity = 0;
	data_en_polarity = 0;

	ctrl_polarity =
	    (data_en_polarity << 2) | (vsync_polarity << 1) | (hsync_polarity);

	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x4, hsync_ctrl);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x8, vsync_period * hsync_period);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0xc,
				vsync_pulse_width * hsync_period);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x10, display_hctl);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x14, display_v_start);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x18, display_v_end);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x1c, active_hctl);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x20, active_v_start);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x24, active_v_end);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x28, dsi_border_clr);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x2c, dsi_underflow_clr);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x30, dsi_hsync_skew);
	MDP_OUTP(MDP_BASE + DSI_VIDEO_BASE + 0x38, ctrl_polarity);
	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);

	mdp_histogram_ctrl_all(TRUE);

	if (!vctrl->sysfs_created) {
		ret = sysfs_create_group(&vctrl->dev->kobj,
			&vsync_fs_attr_group);
		if (ret) {
			pr_err("%s: sysfs group creation failed, ret=%d\n",
				__func__, ret);
			return ret;
		}

		kobject_uevent(&vctrl->dev->kobj, KOBJ_ADD);
		pr_debug("%s: kobject_uevent(KOBJ_ADD)\n", __func__);
		vctrl->sysfs_created = 1;
	}

	return ret;
}
示例#30
0
/**
 * zfcp_port_enqueue - enqueue port to port list of adapter
 * @adapter: adapter where remote port is added
 * @wwpn: WWPN of the remote port to be enqueued
 * @status: initial status for the port
 * @d_id: destination id of the remote port to be enqueued
 * Returns: pointer to enqueued port on success, ERR_PTR on error
 * Locks: config_sema must be held to serialize changes to the port list
 *
 * All port internal structures are set up and the sysfs entry is generated.
 * d_id is used to enqueue ports with a well known address like the Directory
 * Service for nameserver lookup.
 */
struct zfcp_port *zfcp_port_enqueue(struct zfcp_adapter *adapter, u64 wwpn,
				     u32 status, u32 d_id)
{
	struct zfcp_port *port;
	int retval;

	port = kzalloc(sizeof(struct zfcp_port), GFP_KERNEL);
	if (!port)
		return ERR_PTR(-ENOMEM);

	init_waitqueue_head(&port->remove_wq);
	INIT_LIST_HEAD(&port->unit_list_head);
	INIT_WORK(&port->gid_pn_work, zfcp_erp_port_strategy_open_lookup);

	port->adapter = adapter;
	port->d_id = d_id;
	port->wwpn = wwpn;

	/* mark port unusable as long as sysfs registration is not complete */
	atomic_set_mask(status | ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set(&port->refcount, 0);

	dev_set_name(&port->sysfs_device, "0x%016llx",
		     (unsigned long long)wwpn);
	port->sysfs_device.parent = &adapter->ccw_device->dev;

	port->sysfs_device.release = zfcp_sysfs_port_release;
	dev_set_drvdata(&port->sysfs_device, port);

	read_lock_irq(&zfcp_data.config_lock);
	if (!(status & ZFCP_STATUS_PORT_NO_WWPN))
		if (zfcp_get_port_by_wwpn(adapter, wwpn)) {
			read_unlock_irq(&zfcp_data.config_lock);
			goto err_out_free;
		}
	read_unlock_irq(&zfcp_data.config_lock);

	if (device_register(&port->sysfs_device))
		goto err_out_free;

	retval = sysfs_create_group(&port->sysfs_device.kobj,
				    &zfcp_sysfs_port_attrs);

	if (retval) {
		device_unregister(&port->sysfs_device);
		goto err_out;
	}

	zfcp_port_get(port);

	write_lock_irq(&zfcp_data.config_lock);
	list_add_tail(&port->list, &adapter->port_list_head);
	atomic_clear_mask(ZFCP_STATUS_COMMON_REMOVE, &port->status);
	atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING, &port->status);

	write_unlock_irq(&zfcp_data.config_lock);

	zfcp_adapter_get(adapter);
	return port;

err_out_free:
	kfree(port);
err_out:
	return ERR_PTR(-EINVAL);
}