void initialize_mobeam(struct ssp_data *data)
{
	pr_info("[SSP] %s\n", __func__);
	data->mobeam_device = sec_device_create(data, "sec_barcode_emul");

	if (IS_ERR(data->mobeam_device))
		pr_err("[SSP] Failed to create mobeam_dev device\n");

	if (device_create_file(data->mobeam_device, &dev_attr_vendor) < 0)
		pr_err("[SSP] Failed to create device file(%s)!\n",
				dev_attr_vendor.attr.name);

	if (device_create_file(data->mobeam_device, &dev_attr_name) < 0)
		pr_err("[SSP] Failed to create device file(%s)!\n",
				dev_attr_name.attr.name);

	if (device_create_file(data->mobeam_device, &dev_attr_barcode_send) < 0)
		pr_err("[SSP] Failed to create device file(%s)!\n",
				dev_attr_barcode_send.attr.name);

	if (device_create_file(data->mobeam_device, &dev_attr_barcode_led_status) < 0)
		pr_err("[SSP] Failed to create device file(%s)!\n",
				dev_attr_barcode_led_status.attr.name);

	if (device_create_file(data->mobeam_device, &dev_attr_barcode_ver_check) < 0)
		pr_err("[SSP] Failed to create device file(%s)!\n",
				dev_attr_barcode_ver_check.attr.name);

	if (device_create_file(data->mobeam_device, &dev_attr_barcode_test_send) < 0)
		pr_err("[SSP] Failed to create device file(%s)!\n",
				dev_attr_barcode_test_send.attr.name);
	is_beaming = BEAMING_OFF;
}
static int __init gps_bcm4753_init(void)
{
	const char *gps_node = "samsung,exynos54xx-bcm4753";

	struct device_node *root_node = NULL;

	gps_dev = sec_device_create(NULL, "gps");
	BUG_ON(!gps_dev);

	root_node = of_find_compatible_node(NULL, NULL, gps_node);
	if (!root_node) {
		WARN(1, "failed to get device node of bcm4753\n");
		return -ENODEV;
	}

	gps_pwr_on = of_get_gpio(root_node, 0);
	if (!gpio_is_valid(gps_pwr_on)) {
		WARN(1, "Invalied gpio pin : %d\n", gps_pwr_on);
		return -ENODEV;
	}

	if (gpio_request(gps_pwr_on, "GPS_PWR_EN")) {
		WARN(1, "fail to request gpio(GPS_PWR_EN)\n");
		return -ENODEV;
	}
	gpio_direction_output(gps_pwr_on, 0);
	gpio_export(gps_pwr_on, 1);
	gpio_export_link(gps_dev, "GPS_PWR_EN", gps_pwr_on);

	return 0;
}
예제 #3
0
static int __init gps_s5n6420_init(void)
{
	int ret = 0;
	const char *gps_node = "samsung,lsi_s5n6420";

	struct device_node *root_node = NULL;

	gps_dev = sec_device_create(NULL, "gps");
	BUG_ON(!gps_dev);

	root_node = of_find_compatible_node(NULL, NULL, gps_node);

	if (!root_node) {
		WARN(1, "failed to get device node of ske\n");
		ret = -ENODEV;
		goto err_sec_device_create;
	}

	gps_pwr_on = of_get_gpio(root_node, 0);
	if (!gpio_is_valid(gps_pwr_on)) {
		WARN(1, "----Invalied gpio pin : %d\n", gps_pwr_on);
		ret = -ENODEV;
		goto err_sec_device_create;
	}
	gps_reset = of_get_gpio(root_node, 1);
	if (!gpio_is_valid(gps_reset)) {
		WARN(1, "-----Invalied gpio pin : %d\n", gps_reset);
		ret = -ENODEV;
		goto err_sec_device_create;
	}

	if (gpio_request(gps_pwr_on, "GPS_PWR_EN")) {
		WARN(1, "fail to request gpio(GPS_PWR_EN)\n");
		ret = -ENODEV;
		goto err_sec_device_create;
	}
	if (gpio_request(gps_reset, "GPS_RESET")) {
		WARN(1, "fail to request gpio(GPS_RESET)\n");
		ret = -ENODEV;
		goto err_sec_device_create;
	}

	gpio_direction_output(gps_pwr_on, 0);
	gpio_export(gps_pwr_on, 1);
	gpio_export_link(gps_dev, "GPS_PWR_EN", gps_pwr_on);

	gpio_direction_output(gps_reset, 1);
	gpio_export(gps_reset, 1);
	gpio_export_link(gps_dev, "GPS_RESET", gps_reset);

	return 0;

err_sec_device_create:
    WARN(1, "err_sec_device_create");
	sec_device_destroy(gps_dev->devt);
	return ret;

}
int __init dhd_wlan_init_gpio(void)
{
	const char *wlan_node = "samsung,brcm-wlan";
	unsigned int wlan_host_wake_up = -1;
	struct device_node *root_node = NULL;

	wlan_dev = sec_device_create(NULL, "wlan");
	BUG_ON(!wlan_dev);

	root_node = of_find_compatible_node(NULL, NULL, wlan_node);
	if (!root_node) {
		WARN(1, "failed to get device node of bcm4354\n");
		return -ENODEV;
	}

	/* ========== WLAN_PWR_EN ============ */
	wlan_pwr_on = of_get_gpio(root_node, 0);
	if (!gpio_is_valid(wlan_pwr_on)) {
		WARN(1, "Invalied gpio pin : %d\n", wlan_pwr_on);
		return -ENODEV;
	}

	if (gpio_request(wlan_pwr_on, "WLAN_REG_ON")) {
		WARN(1, "fail to request gpio(WLAN_REG_ON)\n");
		return -ENODEV;
	}
#ifdef CONFIG_BCMDHD_PCIE
	gpio_direction_output(wlan_pwr_on, 1);
#else
	gpio_direction_output(wlan_pwr_on, 0);
#endif /* CONFIG_BCMDHD_PCIE */
	gpio_export(wlan_pwr_on, 1);
	gpio_export_link(wlan_dev, "WLAN_REG_ON", wlan_pwr_on);
	msleep(WIFI_TURNON_DELAY);

	/* ========== WLAN_HOST_WAKE ============ */
	wlan_host_wake_up = of_get_gpio(root_node, 1);
	if (!gpio_is_valid(wlan_host_wake_up)) {
		WARN(1, "Invalied gpio pin : %d\n", wlan_host_wake_up);
		return -ENODEV;
	}

	if (gpio_request(wlan_host_wake_up, "WLAN_HOST_WAKE")) {
		WARN(1, "fail to request gpio(WLAN_HOST_WAKE)\n");
		return -ENODEV;
	}
	gpio_direction_input(wlan_host_wake_up);
	gpio_export(wlan_host_wake_up, 1);
	gpio_export_link(wlan_dev, "WLAN_HOST_WAKE", wlan_host_wake_up);

	wlan_host_wake_irq = gpio_to_irq(wlan_host_wake_up);

	return 0;
}
예제 #5
0
static int __init muic_notifier_init(void)
{
	int ret = 0;

	pr_info("%s\n", __func__);

	switch_device = sec_device_create(NULL, "switch");
	if (IS_ERR(switch_device)) {
		pr_err("%s Failed to create device(switch)!\n", __func__);
		ret = -ENODEV;
		goto out;
	}

	BLOCKING_INIT_NOTIFIER_HEAD(&(muic_notifier.notifier_call_chain));
	muic_notifier.cmd = MUIC_NOTIFY_CMD_DETACH;
	muic_notifier.attached_dev = ATTACHED_DEV_UNKNOWN_MUIC;

out:
	return ret;
}
예제 #6
0
static int __init sec_misc_init(void)
{
	int ret = 0;
	int i;

	ret = misc_register(&sec_misc_device);
	if (ret < 0) {
		printk(KERN_ERR "misc_register failed!\n");
		goto failed_register_misc;
	}
	sec_misc_dev = sec_device_create(NULL, "sec_misc");
	if (IS_ERR(sec_misc_dev)) {
		printk(KERN_ERR "failed to create device!\n");
		ret = -ENODEV;
		goto failed_create_device;
	}

	for (i = 0; i < ARRAY_SIZE(sec_misc_attrs) ; i++) {
		ret = device_create_file(sec_misc_dev, sec_misc_attrs[i]);
		if (ret < 0) {
			pr_err("failed to create sec misc device file \n");
			goto failed_create_device_file;
		}
	}

	wake_lock_init(&sec_misc_wake_lock, WAKE_LOCK_SUSPEND, "sec_misc");

	return 0;

failed_create_device_file:
	if (i) {
		for (--i; i >= 0; i--)
			device_remove_file(sec_misc_dev, sec_misc_attrs[i]);
	}
failed_create_device:
	misc_deregister(&sec_misc_device);
failed_register_misc:
	return ret;
}
예제 #7
0
static int __init sec_bsp_init(void)
{
	struct proc_dir_entry *entry;

	entry = proc_create("boot_stat",S_IRUGO, NULL,
							&sec_boot_stat_proc_fops);
	if (!entry)
		return -ENOMEM;

//	boot_events[SYSTEM_START_LK].time = bootloader_start;
//	boot_events[SYSTEM_LK_LOGO_DISPLAY].time = bootloader_display;
//	boot_events[SYSTEM_END_LK].time = bootloader_end;

//	sec_class = class_create(THIS_MODULE, "sec");
	sec_bsp_dev = sec_device_create(NULL, "bsp");
	BUG_ON(!sec_bsp_dev);
	if (IS_ERR(sec_bsp_dev))
		pr_err("%s:Failed to create devce\n",__func__);

	if (device_create_file(sec_bsp_dev, &dev_attr_boot_stat) < 0)
		pr_err("%s: Failed to create device file\n",__func__);

	return 0;
}
예제 #8
0
static int __init muic_notifier_init(void)
{
	int ret = 0;

	printk(KERN_DEBUG "[muic] %s\n", __func__);

#ifdef CONFIG_SEC_SYSFS
	switch_device = sec_device_create(NULL, "switch");
	if (IS_ERR(switch_device)) {
		printk(KERN_ERR "[muic] Failed to create device(switch)!\n");
		ret = -ENODEV;
		goto out;
	}
#endif

	BLOCKING_INIT_NOTIFIER_HEAD(&(muic_notifier.notifier_call_chain));
	muic_notifier.cmd = MUIC_NOTIFY_CMD_DETACH;
	muic_notifier.attached_dev = ATTACHED_DEV_UNKNOWN_MUIC;

#ifdef CONFIG_SEC_SYSFS
out:
#endif
	return ret;
}
static int max77828_rgb_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct max77828_rgb_platform_data *pdata;
	struct max77828_rgb *max77828_rgb;
	struct max77828_dev *max77828_dev = dev_get_drvdata(dev->parent);
	char temp_name[4][40] = {{0,},}, name[40] = {0,}, *p;
	int i, ret;

#ifdef CONFIG_OF
	pdata = max77828_rgb_parse_dt(dev);
	if (unlikely(IS_ERR(pdata)))
		return PTR_ERR(pdata);
#else
	pdata = dev_get_platdata(dev);
#endif
	pr_info("leds-max77828-rgb: %s\n", __func__);

	max77828_rgb = devm_kzalloc(dev, sizeof(struct max77828_rgb), GFP_KERNEL);
	if (unlikely(!max77828_rgb))
		return -ENOMEM;

	for (i = 0; i < 4; i++) {
		ret = snprintf(name, 30, "%s", pdata->name[i])+1;
		if (1 > ret)
			goto alloc_err_flash;

		p = devm_kzalloc(dev, ret, GFP_KERNEL);
		if (unlikely(!p))
			goto alloc_err_flash;

		strcpy(p, name);
		strcpy(temp_name[i], name);
		max77828_rgb->led[i].name = p;
		max77828_rgb->led[i].brightness_set = max77828_rgb_set;
		max77828_rgb->led[i].brightness_get = max77828_rgb_get;
		max77828_rgb->led[i].max_brightness = LED_MAX_CURRENT;

		ret = led_classdev_register(dev, &max77828_rgb->led[i]);
		if (IS_ERR_VALUE(ret)) {
			dev_err(dev, "unable to register RGB : %d\n", ret);
			goto alloc_err_flash_plus;
		}
		ret = sysfs_create_group(&max77828_rgb->led[i].dev->kobj,
						&common_led_attr_group);
		if (ret < 0) {
			dev_err(dev, "can not register sysfs attribute\n");
			goto register_err_flash;
		}
	}

	led_dev = sec_device_create(max77828_rgb, "led");
	if (IS_ERR(led_dev)) {
		dev_err(dev, "Failed to create device for samsung specific led\n");
		goto alloc_err_flash;
	}

	ret = sysfs_create_group(&led_dev->kobj, &sec_led_attr_group);
	if (ret < 0) {
		dev_err(dev, "Failed to create sysfs group for samsung specific led\n");
		goto alloc_err_flash;
	}

	platform_set_drvdata(pdev, max77828_rgb);

	max77828_rgb->i2c = max77828_dev->led;

	return 0;

register_err_flash:
	led_classdev_unregister(&max77828_rgb->led[i]);
alloc_err_flash_plus:
	devm_kfree(dev, temp_name[i]);
alloc_err_flash:
	while (i--) {
		led_classdev_unregister(&max77828_rgb->led[i]);
		devm_kfree(dev, temp_name[i]);
	}
	devm_kfree(dev, max77828_rgb);
	return -ENOMEM;
}
static int max77843_rgb_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct max77843_rgb_platform_data *pdata;
	struct max77843_rgb *max77843_rgb;
	struct max77843_dev *max77843_dev = dev_get_drvdata(dev->parent);
	char temp_name[4][40] = {{0,},}, name[40] = {0,}, *p;
	int i, ret;

	pr_info("leds-max77843-rgb: %s\n", __func__);

#ifdef CONFIG_OF
	pdata = max77843_rgb_parse_dt(dev);
	if (unlikely(IS_ERR(pdata)))
		return PTR_ERR(pdata);
#else
	pdata = dev_get_platdata(dev);
#endif

	max77843_rgb = devm_kzalloc(dev, sizeof(struct max77843_rgb), GFP_KERNEL);
	if (unlikely(!max77843_rgb))
		return -ENOMEM;
	pr_info("leds-max77843-rgb: %s 1 \n", __func__);

	max77843_rgb->i2c = max77843_dev->i2c;

	for (i = 0; i < 4; i++) {
		ret = snprintf(name, 30, "%s", pdata->name[i])+1;
		if (1 > ret)
			goto alloc_err_flash;

		p = devm_kzalloc(dev, ret, GFP_KERNEL);
		if (unlikely(!p))
			goto alloc_err_flash;

		strcpy(p, name);
		strcpy(temp_name[i], name);
		max77843_rgb->led[i].name = p;
		max77843_rgb->led[i].brightness_set = max77843_rgb_set;
		max77843_rgb->led[i].brightness_get = max77843_rgb_get;
		max77843_rgb->led[i].max_brightness = LED_MAX_CURRENT;

		ret = led_classdev_register(dev, &max77843_rgb->led[i]);
		if (IS_ERR_VALUE(ret)) {
			dev_err(dev, "unable to register RGB : %d\n", ret);
			goto alloc_err_flash_plus;
		}
		ret = sysfs_create_group(&max77843_rgb->led[i].dev->kobj,
						&common_led_attr_group);
		if (ret) {
			dev_err(dev, "can not register sysfs attribute\n");
			goto register_err_flash;
		}
	}

	led_dev = sec_device_create(max77843_rgb, "led");
	if (IS_ERR(led_dev)) {
		dev_err(dev, "Failed to create device for samsung specific led\n");
		goto register_err_flash;
	}


	ret = sysfs_create_group(&led_dev->kobj, &sec_led_attr_group);
	if (ret < 0) {
		dev_err(dev, "Failed to create sysfs group for samsung specific led\n");
		goto device_create_err;
	}

	platform_set_drvdata(pdev, max77843_rgb);
#if defined(CONFIG_LEDS_USE_ED28) && defined(CONFIG_SEC_FACTORY)
	if( lcdtype == 0 && jig_status == false) {
		max77843_rgb_set_state(&max77843_rgb->led[RED], led_dynamic_current, LED_ALWAYS_ON);
	}
#endif
	lcdtype_color = lcdtype >> 0x10;
	if (lcdtype_color == 51)
		led_color_dynamic_current = 0x5A;

	pr_info("leds-max77843-rgb: %s done\n", __func__);

	return 0;

device_create_err:
	sec_device_destroy(led_dev->devt);
register_err_flash:
	led_classdev_unregister(&max77843_rgb->led[i]);
alloc_err_flash_plus:
	devm_kfree(dev, temp_name[i]);
alloc_err_flash:
	while (i--) {
		led_classdev_unregister(&max77843_rgb->led[i]);
		devm_kfree(dev, temp_name[i]);
	}
	devm_kfree(dev, max77843_rgb);
	return -ENOMEM;
}
static int max77833_haptic_probe(struct platform_device *pdev)
{
	int error = 0;
	struct max77833_dev *max77833 = dev_get_drvdata(pdev->dev.parent);
	struct max77833_platform_data *max77833_pdata
		= dev_get_platdata(max77833->dev);
	struct max77833_haptic_platform_data *pdata
		= max77833_pdata->haptic_data;
	struct max77833_haptic_data *hap_data;

	pr_info("[VIB] ++ %s\n", __func__);

#if defined(CONFIG_OF)
	if (pdata == NULL) {
		pdata = of_max77833_haptic_dt(&pdev->dev);
		if (!pdata) {
			pr_err("[VIB] max77833-haptic : %s not found haptic dt!\n",
					__func__);
			return -1;
		}
	}
#else
	if (pdata == NULL) {
		pr_err("[VIB] %s: no pdata\n", __func__);
		return -ENODEV;
	}
#endif /* CONFIG_OF */

	hap_data = kzalloc(sizeof(struct max77833_haptic_data), GFP_KERNEL);
	if (!hap_data) {
		pr_err("[VIB] %s: no hap_pdata\n", __func__);
		kfree(pdata);
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, hap_data);
	g_hap_data = hap_data;
	hap_data->max77833 = max77833;
	hap_data->i2c = max77833->i2c;
	hap_data->pdata = pdata;

	hap_data->workqueue = create_singlethread_workqueue("hap_work");
	if (NULL == hap_data->workqueue) {
		error = -EFAULT;
		pr_err("[VIB] Failed to create workqueue, err num: %d\n", error);
		goto err_work_queue;
	}
	INIT_WORK(&(hap_data->work), haptic_work);
	spin_lock_init(&(hap_data->lock));

	hap_data->pwm = pwm_request(hap_data->pdata->pwm_id, "vibrator");
	if (IS_ERR(hap_data->pwm)) {
		error = -EFAULT;
		pr_err("[VIB] Failed to request pwm, err num: %d\n", error);
		goto err_pwm_request;
	}

	pwm_config(hap_data->pwm, pdata->period / 2, pdata->period);
	prev_duty = hap_data->pdata->period / 2;
	vibetonz_clk_on(&pdev->dev, true);

	/* hrtimer init */
	hrtimer_init(&hap_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hap_data->timer.function = haptic_timer_func;

	/* timed_output_dev init*/
	hap_data->tout_dev.name = "vibrator";
	hap_data->tout_dev.get_time = haptic_get_time;
	hap_data->tout_dev.enable = haptic_enable;

	motor_dev = sec_device_create(hap_data, "motor");
	if (IS_ERR(motor_dev)) {
		error = -ENODEV;
		pr_err("[VIB] Failed to create device\
				for samsung specific motor, err num: %d\n", error);
		goto exit_sec_devices;
	}
	error = sysfs_create_group(&motor_dev->kobj, &sec_motor_attr_group);
	if (error) {
		error = -ENODEV;
		pr_err("[VIB] Failed to create sysfs group\
				for samsung specific motor, err num: %d\n", error);
		goto exit_sysfs;
	}

#ifdef CONFIG_ANDROID_TIMED_OUTPUT
	error = timed_output_dev_register(&hap_data->tout_dev);
	if (error < 0) {
		error = -EFAULT;
		pr_err("[VIB] Failed to register timed_output : %d\n", error);
		goto err_timed_output_register;
	}
#endif

	vibtonz_en = max77833_vibtonz_en;
	vibtonz_pwm = max77833_vibtonz_pwm;
	prev_temperature_level = 1;

	/* autoresonance range setting */
	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_CONFIG, 0x00);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_CONFIG, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_MIN_FREQ_LOW, pdata->auto_res_min_low);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_MIN_FREQ_LOW, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_MAX_FREQ_LOW, pdata->auto_res_max_low);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_MAX_FREQ_LOW, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_INIT_GUESS_LOW, pdata->auto_res_init_low);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_INIT_GUESS_LOW, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_NOMINAL_STRENGTH, pdata->nominal_strength);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_NOMINAL_STRENGTH, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_RES_MIN_FREQ_HIGH, pdata->auto_res_min_high);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_RES_MIN_FREQ_HIGH, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_RES_MAX_FREQ_HIGH, pdata->auto_res_max_high);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_RES_MAX_FREQ_HIGH, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_INIT_GUESS_HIGH, pdata->auto_res_init_high);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_INIT_GUESS_HIGH, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_LOCK_WINDOW, pdata->auto_res_lock_window);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_LOCK_WINDOW, error);
	}

	error = max77833_write_reg(hap_data->i2c,
		MAX77833_AUTORES_UPDATE_FREQ, pdata->auto_res_update_freq);
	if (error < 0) {
		pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
				__func__, MAX77833_AUTORES_UPDATE_FREQ, error);
	}

	if (!pdata->auto_res_enable) {
		error = max77833_write_reg(hap_data->i2c, MAX77833_OPTION_REG1, 0x11);
		if (error < 0) {
			pr_err("[VIB] %s Failed to write REG(0x%02x) [%d]\n",
					__func__, MAX77833_OPTION_REG1, error);
		}
	}
	return error;

err_timed_output_register:
	sysfs_remove_group(&motor_dev->kobj, &sec_motor_attr_group);
exit_sysfs:
	sec_device_destroy(motor_dev->devt);
exit_sec_devices:
	pwm_free(hap_data->pwm);
err_pwm_request:
	destroy_workqueue(hap_data->workqueue);
err_work_queue:
	kfree(hap_data);
	kfree(pdata);
	g_hap_data = NULL;
	return error;
}
예제 #12
0
static int max77843_haptic_probe(struct platform_device *pdev)
{
	int error = 0;
	struct max77843_dev *max77843 = dev_get_drvdata(pdev->dev.parent);
	struct max77843_platform_data *max77843_pdata
		= dev_get_platdata(max77843->dev);
	struct max77843_haptic_platform_data *pdata
		= max77843_pdata->haptic_data;
	struct max77843_haptic_data *hap_data;

	pr_info("[VIB] ++ %s\n", __func__);

#if defined(CONFIG_OF)
	if (pdata == NULL) {
		pdata = of_max77843_haptic_dt(&pdev->dev);
		if (!pdata) {
			pr_err("[VIB] max77843-haptic : %s not found haptic dt!\n",
					__func__);
			return -1;
		}
	}
#else
	if (pdata == NULL) {
		pr_err("%s: no pdata\n", __func__);
		return -ENODEV;
	}
#endif /* CONFIG_OF */

	hap_data = kzalloc(sizeof(struct max77843_haptic_data), GFP_KERNEL);
	if (!hap_data) {
		kfree(pdata);
		return -ENOMEM;
	}
	platform_set_drvdata(pdev, hap_data);
	g_hap_data = hap_data;
	hap_data->max77843 = max77843;
	hap_data->i2c = max77843->i2c;
	hap_data->pdata = pdata;

	hap_data->workqueue = create_singlethread_workqueue("hap_work");
	if (NULL == hap_data->workqueue) {
		error = -EFAULT;
		pr_err("[VIB] Failed to create workqueue, err num: %d\n", error);
		goto err_work_queue;
	}
	INIT_WORK(&(hap_data->work), haptic_work);
	spin_lock_init(&(hap_data->lock));

	hap_data->pwm = pwm_request(hap_data->pdata->pwm_id, "vibrator");
	if (IS_ERR(hap_data->pwm)) {
		error = -EFAULT;
		pr_err("[VIB] Failed to request pwm, err num: %d\n", error);
		goto err_pwm_request;
	}

	pwm_config(hap_data->pwm, pdata->period / 2, pdata->period);

	vibetonz_clk_on(&pdev->dev, true);
	if (pdata->init_hw)
		pdata->init_hw();
	else
		hap_data->regulator
			= regulator_get(NULL, pdata->regulator_name);

	if (IS_ERR(hap_data->regulator)) {
		error = -EFAULT;
		pr_err("[VIB] Failed to get vmoter regulator, err num: %d\n", error);
		goto err_regulator_get;
	}
	/* hrtimer init */
	hrtimer_init(&hap_data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
	hap_data->timer.function = haptic_timer_func;

	/* timed_output_dev init*/
	hap_data->tout_dev.name = "vibrator";
	hap_data->tout_dev.get_time = haptic_get_time;
	hap_data->tout_dev.enable = haptic_enable;

	hap_data->resumed = false;

	motor_dev = sec_device_create(hap_data, "motor");
	if (IS_ERR(motor_dev)) {
		error = -ENODEV;
		pr_err("[VIB] Failed to create device\
				for samsung specific motor, err num: %d\n", error);
		goto exit_sec_devices;
	}
	error = sysfs_create_group(&motor_dev->kobj, &sec_motor_attr_group);
	if (error) {
		error = -ENODEV;
		pr_err("[VIB] Failed to create sysfs group\
				for samsung specific motor, err num: %d\n", error);
		goto exit_sysfs;
	}

#ifdef CONFIG_ANDROID_TIMED_OUTPUT
	error = timed_output_dev_register(&hap_data->tout_dev);
	if (error < 0) {
		error = -EFAULT;
		pr_err("[VIB] Failed to register timed_output : %d\n", error);
		goto err_timed_output_register;
	}
#endif

	pr_debug("[VIB] -- %s\n", __func__);

	return error;

err_timed_output_register:
	sysfs_remove_group(&motor_dev->kobj, &sec_motor_attr_group);
exit_sysfs:
	sec_device_destroy(motor_dev->devt);
exit_sec_devices:
	regulator_put(hap_data->regulator);
err_regulator_get:
	pwm_free(hap_data->pwm);
err_pwm_request:
	destroy_workqueue(hap_data->workqueue);
err_work_queue:
	kfree(hap_data);
	kfree(pdata);
	g_hap_data = NULL;
	return error;
}
예제 #13
0
static int matrix_keypad_probe(struct platform_device *pdev)
{
	struct matrix_keypad_platform_data *pdata;
	struct matrix_keypad *keypad;
	struct input_dev *input_dev;
#ifdef CONFIG_SUPPORT_KEYPAD_LED
	struct device *sec_keypad;
#endif
	int err;

	pdata = dev_get_platdata(&pdev->dev);
	if (!pdata) {
		pdata = matrix_keypad_parse_dt(&pdev->dev);
		if (IS_ERR(pdata)) {
			dev_err(&pdev->dev, "no platform data defined\n");
			return PTR_ERR(pdata);
		}
	} else if (!pdata->keymap_data) {
		dev_err(&pdev->dev, "no keymap data defined\n");
		return -EINVAL;
	}

	keypad = kzalloc(sizeof(struct matrix_keypad), GFP_KERNEL);
	input_dev = input_allocate_device();
	if (!keypad || !input_dev) {
		err = -ENOMEM;
		goto err_free_mem;
	}

	keypad->input_dev = input_dev;
	keypad->pdata = pdata;
	keypad->row_shift = get_count_order(pdata->num_col_gpios);
	keypad->stopped = true;
	INIT_DELAYED_WORK(&keypad->work, matrix_keypad_scan);
	spin_lock_init(&keypad->lock);

	if (pdata->project)
		input_dev->name		= pdata->project;
	else
		input_dev->name		= pdev->name;

	input_dev->id.bustype	= BUS_HOST;
	input_dev->dev.parent	= &pdev->dev;
	input_dev->open		= matrix_keypad_start;
	input_dev->close	= matrix_keypad_stop;

	err = matrix_keypad_build_keymap(pdata->keymap_data, NULL,
					 pdata->num_row_gpios,
					 pdata->num_col_gpios,
					 NULL, input_dev);
	if (err) {
		dev_err(&pdev->dev, "failed to build keymap\n");
		goto err_free_mem;
	}

	if (!pdata->no_autorepeat)
		__set_bit(EV_REP, input_dev->evbit);
	input_set_capability(input_dev, EV_MSC, MSC_SCAN);
	input_set_drvdata(input_dev, keypad);

	err = matrix_keypad_init_gpio(pdev, keypad);
	if (err)
		goto err_free_mem;

	err = input_register_device(keypad->input_dev);
	if (err)
		goto err_free_gpio;

#ifdef CONFIG_SUPPORT_KEYPAD_LED
/* keypad led control */
	sec_keypad = sec_device_create(pdata, "sec_keypad");
	if (IS_ERR(sec_keypad))
		dev_err(&pdev->dev,"Failed to create device(sec_key)!\n");

	err = device_create_file(sec_keypad, &dev_attr_brightness);
	if (err) {
		dev_err(&pdev->dev,"Failed to create device file in sysfs entries(%s)!\n",
				dev_attr_brightness.attr.name);
	}

	dev_set_drvdata(sec_keypad, pdata);

	pdata->vddo_vreg = regulator_get(&pdev->dev,"vddo");
	if (IS_ERR(pdata->vddo_vreg)){
		pdata->vddo_vreg = NULL;
		printk(KERN_INFO "pdata->vddo_vreg error\n");
		err = -EPERM;
		goto err_free_gpio;
	}
#endif
	device_init_wakeup(&pdev->dev, pdata->wakeup);
	platform_set_drvdata(pdev, keypad);

	return 0;

err_free_gpio:
	matrix_keypad_free_gpio(keypad);
err_free_mem:
	input_free_device(input_dev);
	kfree(keypad);
	return err;
}