static irqreturn_t fsa9485_irq_thread(int irq, void *data)
{
	struct fsa9485_usbsw *usbsw = data;
	struct i2c_client *client = usbsw->client;
	int intr, intr2, detect;

	/* FSA9480 : Read interrupt -> Read Device
	 * FSA9485 : Read Device -> Read interrupt */

	dev_info(&usbsw->client->dev, "%s\n", __func__);

	/* read and clear interrupt status bits */
	intr = i2c_smbus_read_word_data(client, FSA9485_REG_INT1);
	intr2 = intr >> 8;
	dev_info(&client->dev, "%s: intr : 0x%02x intr2 : 0x%02x\n",
					__func__, intr & 0xff, intr2);

	/* device detection */
	mutex_lock(&usbsw->mutex);
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
	if((intr&0xff) == 0x00 && intr2 == 0x04)
		detect = fsa9485_detect_lanhub(usbsw);
	else
		detect = fsa9485_detect_dev(usbsw);
#else
	detect = fsa9485_detect_dev(usbsw);
#endif
	mutex_unlock(&usbsw->mutex);
	pr_info("%s: detect dev_adc: 0x%02x\n", __func__, detect);


	if (intr < 0) {
		msleep(100);
		dev_err(&client->dev, "%s: err 0x%02x\n", __func__, intr);
		intr = i2c_smbus_read_word_data(client, FSA9485_REG_INT1);
		if (intr < 0)
			dev_err(&client->dev,
				"%s: err at read 0x%02x\n", __func__, intr);
		fsa9485_reg_init(usbsw);
		return IRQ_HANDLED;
	} else if (intr == 0) {
		/* interrupt was fired, but no status bits were set,
		so device was reset. In this case, the registers were
		reset to defaults so they need to be reinitialised. */
		fsa9485_reg_init(usbsw);
	}
	return IRQ_HANDLED;
}
Exemplo n.º 2
0
static ssize_t fsa9485_reset(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t count)
{
	struct fsa9485_usbsw *usbsw = dev_get_drvdata(dev);
	struct i2c_client *client = usbsw->client;
	int ret;

	if (!strncmp(buf, "1", 1)) {
		dev_info(&client->dev, "fsa9480 reset after delay 1000 msec.\n");
		mdelay(1000);
		ret = i2c_smbus_write_byte_data(client,
					FSA9485_REG_MANUAL_OVERRIDES1, 0x01);
		if (ret < 0)
				dev_err(&client->dev,
					"cannot soft reset, err %d\n", ret);

	dev_info(&client->dev, "fsa9480_reset_control done!\n");
	} else {
		dev_info(&client->dev,
					"fsa9480_reset_control, but not reset_value!\n");
	}

	fsa9485_reg_init(usbsw);

	return count;
}
Exemplo n.º 3
0
static int __devinit fsa9485_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct fsa9485_usbsw *usbsw;
	int ret = 0;
	struct input_dev *input;
	struct device *switch_dev;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	input = input_allocate_device();
	usbsw = kzalloc(sizeof(struct fsa9485_usbsw), GFP_KERNEL);
	if (!usbsw || !input) {
		dev_err(&client->dev, "failed to allocate driver data\n");
		kfree(usbsw);
		return -ENOMEM;
	}

	usbsw->input = input;
	input->name = client->name;
	input->phys = "deskdock-key/input0";
	input->dev.parent = &client->dev;
	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0001;

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

	input_set_capability(input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(input, EV_KEY, KEY_VOLUMEDOWN);
	input_set_capability(input, EV_KEY, KEY_PLAYPAUSE);
	input_set_capability(input, EV_KEY, KEY_PREVIOUSSONG);
	input_set_capability(input, EV_KEY, KEY_NEXTSONG);

	ret = input_register_device(input);
	if (ret) {
		dev_err(&client->dev,
			"input_register_device %s: err %d\n", __func__, ret);
		input_free_device(input);
		kfree(usbsw);
		return ret;
	}

	usbsw->client = client;
	usbsw->pdata = client->dev.platform_data;
	if (!usbsw->pdata)
		goto fail1;

	i2c_set_clientdata(client, usbsw);

	mutex_init(&usbsw->mutex);

	local_usbsw = usbsw;

	if (usbsw->pdata->cfg_gpio)
		usbsw->pdata->cfg_gpio();

	fsa9485_reg_init(usbsw);

	uart_connecting = 0;

	ret = sysfs_create_group(&client->dev.kobj, &fsa9485_group);
	if (ret) {
		dev_err(&client->dev,
				"failed to create fsa9485 attribute group\n");
		goto fail2;
	}

	/* make sysfs node /sys/class/sec/switch/usb_state */
	switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
	if (IS_ERR(switch_dev)) {
		pr_err("[FSA9485] Failed to create device (switch_dev)!\n");
		ret = PTR_ERR(switch_dev);
		goto fail2;
	}

	ret = device_create_file(switch_dev, &dev_attr_usb_state);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (usb_state)!\n");
		goto err_create_file_state;
	}

	ret = device_create_file(switch_dev, &dev_attr_adc);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (adc)!\n");
		goto err_create_file_adc;
	}

	ret = device_create_file(switch_dev, &dev_attr_reset_switch);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (reset_switch)!\n");
		goto err_create_file_reset_switch;
	}

	dev_set_drvdata(switch_dev, usbsw);
	/* fsa9485 dock init*/
	if (usbsw->pdata->dock_init)
		usbsw->pdata->dock_init();

	/* fsa9485 reset */
	if (usbsw->pdata->reset_cb)
		usbsw->pdata->reset_cb();

	/* set fsa9485 init flag. */
	if (usbsw->pdata->set_init_flag)
		usbsw->pdata->set_init_flag();

	/* initial cable detection */
	INIT_DELAYED_WORK(&usbsw->init_work, fsa9485_init_detect);
	schedule_delayed_work(&usbsw->init_work, msecs_to_jiffies(2700));

	return 0;

err_create_file_reset_switch:
	device_remove_file(switch_dev, &dev_attr_reset_switch);
err_create_file_adc:
	device_remove_file(switch_dev, &dev_attr_adc);
err_create_file_state:
	device_remove_file(switch_dev, &dev_attr_usb_state);
fail2:
	if (client->irq)
		free_irq(client->irq, usbsw);
fail1:
	input_unregister_device(input);
	mutex_destroy(&usbsw->mutex);
	i2c_set_clientdata(client, NULL);
	kfree(usbsw);
	return ret;
}
Exemplo n.º 4
0
static irqreturn_t fsa9485_irq_thread(int irq, void *data)
{
	struct fsa9485_usbsw *usbsw = data;
	struct i2c_client *client = usbsw->client;
	int intr, intr2, detect;

	/* FSA9485 : Read interrupt -> Read Device
	 FSA9485 : Read Device -> Read interrupt */

	pr_info("fsa9485_irq_thread is called\n");
	/* device detection */
	mutex_lock(&usbsw->mutex);
	detect = fsa9485_detect_dev(usbsw);
	mutex_unlock(&usbsw->mutex);
	pr_info("%s: detect dev_adc: %x\n", __func__, detect);

	/* read and clear interrupt status bits */
	intr = i2c_smbus_read_word_data(client, FSA9485_REG_INT1);
	dev_info(&client->dev, "%s: intr : 0x%x intr2 : 0x%x\n",
					__func__, intr & 0xff, intr >> 8);
	intr2 = intr >> 8;

	if (intr < 0) {
		msleep(100);
		dev_err(&client->dev, "%s: err %d\n", __func__, intr);
		intr = i2c_smbus_read_word_data(client, FSA9485_REG_INT1);
		if (intr < 0)
			dev_err(&client->dev,
				"%s: err at read %d\n", __func__, intr);
		fsa9485_reg_init(usbsw);
		return IRQ_HANDLED;
	} else if (intr == 0) {
		/* interrupt was fired, but no status bits were set,
		so device was reset. In this case, the registers were
		reset to defaults so they need to be reinitialised. */
		fsa9485_reg_init(usbsw);
	}
	/* ADC_value(key pressed) changed at AV_Dock.*/
	if (intr2) {
		if (intr2 & 0x4) { /* for adc change */
			fsa9485_handle_dock_vol_key(usbsw, detect);
			dev_info(&client->dev,
					"intr2: 0x%x, adc_val: %x\n",
							intr2, detect);
		} else if (intr2 & 0x2) { /* for smart dock */
			i2c_smbus_read_word_data(client, FSA9485_REG_INT1);

		} else if (intr2 & 0x1) { /* for av change (desk dock, hdmi) */
			dev_info(&client->dev,
				"%s enter Av charing\n", __func__);
			fsa9485_detect_dev(usbsw);
		} else {
			dev_info(&client->dev,
				"%s intr2 but, nothing happend, intr2: 0x%x\n",
				__func__, intr2);
		}
		return IRQ_HANDLED;
	}

	return IRQ_HANDLED;
}
static int __devinit fsa9485_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct fsa9485_usbsw *usbsw;
	int ret = 0;
	struct input_dev *input;
	struct device *switch_dev;
	struct fsa9485_platform_data *pdata;

	dev_info(&client->dev, "%s\n", __func__);
	if (client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
			sizeof(struct fsa9485_platform_data), GFP_KERNEL);
		if (!pdata) {
			dev_err(&client->dev, "Failed to allocate memory\n");
			return -ENOMEM;
		}
		pdata = &fsa9485_pdata;
		fsa9485_parse_dt(&client->dev, pdata);
		client->irq = gpio_to_irq(pdata->gpio_int);
	} else
		pdata = client->dev.platform_data;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	input = input_allocate_device();
	if (!input) {
		dev_err(&client->dev, "failed to allocate input device data\n");
		return -ENOMEM;
	}

	usbsw = kzalloc(sizeof(struct fsa9485_usbsw), GFP_KERNEL);
	if (!usbsw) {
		dev_err(&client->dev, "failed to allocate driver data\n");
		input_free_device(input);
		return -ENOMEM;
	}

	usbsw->input = input;
	input->name = client->name;
	input->phys = "deskdock-key/input0";
	input->dev.parent = &client->dev;
	input->id.bustype = BUS_HOST;
	input->id.vendor = 0x0001;
	input->id.product = 0x0001;
	input->id.version = 0x0001;

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

	input_set_capability(input, EV_KEY, KEY_VOLUMEUP);
	input_set_capability(input, EV_KEY, KEY_VOLUMEDOWN);
	input_set_capability(input, EV_KEY, KEY_PLAYPAUSE);
	input_set_capability(input, EV_KEY, KEY_PREVIOUSSONG);
	input_set_capability(input, EV_KEY, KEY_NEXTSONG);

	ret = input_register_device(input);
	if (ret) {
		dev_err(&client->dev,
			"input_register_device %s: err %d\n", __func__, ret);
		input_free_device(input);
		kfree(usbsw);
		return ret;
	}

	usbsw->client = client;
	usbsw->pdata = pdata;
	if (!usbsw->pdata)
		goto fail1;
#if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK)
	usbsw->is_factory_start = false;
#endif /* !CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK */

	i2c_set_clientdata(client, usbsw);

	mutex_init(&usbsw->mutex);

	local_usbsw = usbsw;

	if (usbsw->pdata->cfg_gpio)
		usbsw->pdata->cfg_gpio();

	fsa9485_reg_init(usbsw);

	uart_connecting = 0;

	ret = sysfs_create_group(&client->dev.kobj, &fsa9485_group);
	if (ret) {
		dev_err(&client->dev,
				"failed to create fsa9485 attribute group\n");
		goto fail2;
	}

	/* make sysfs node /sys/class/sec/switch/usb_state */
	switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
	if (IS_ERR(switch_dev)) {
		pr_err("[FSA9485] Failed to create device (switch_dev)!\n");
		ret = PTR_ERR(switch_dev);
		goto fail2;
	}

	ret = device_create_file(switch_dev, &dev_attr_usb_state);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (usb_state)!\n");
		goto fail2;
	}

	ret = device_create_file(switch_dev, &dev_attr_adc);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (adc)!\n");
		goto err_create_file_state;
	}

	ret = device_create_file(switch_dev, &dev_attr_reset_switch);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (reset_switch)!\n");
		goto err_create_file_adc;
	}

#if !defined(CONFIG_MUIC_FSA9485_SUPPORT_CAR_DOCK)
	ret = device_create_file(switch_dev, &dev_attr_apo_factory);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (apo_factory)!\n");
		goto err_create_file_reset_switch;
	}
#endif

	dev_set_drvdata(switch_dev, usbsw);
	/* fsa9485 dock init*/
	if (usbsw->pdata->dock_init)
		usbsw->pdata->dock_init();

	/* fsa9485 reset */
	if (usbsw->pdata->reset_cb)
		usbsw->pdata->reset_cb();

	/* set fsa9485 init flag. */
	if (usbsw->pdata->set_init_flag)
		usbsw->pdata->set_init_flag();


	local_usbsw->dock_ready = 0;
	local_usbsw->mhl_ready = 0;
#ifdef CONFIG_MUIC_FSA9485_SUPPORT_LANHUB
	local_usbsw->previous_dock = 0;
	local_usbsw->lanhub_ta_status = 0;
#endif

	/* initial cable detection */
	INIT_DELAYED_WORK(&usbsw->init_work, fsa9485_init_detect);
	if(poweroff_charging)
		schedule_delayed_work(&usbsw->init_work, msecs_to_jiffies(1000));
	else
#ifdef CONFIG_SEC_BERLUTI_PROJECT
		schedule_delayed_work(&usbsw->init_work, msecs_to_jiffies(100));
#else
		schedule_delayed_work(&usbsw->init_work, msecs_to_jiffies(3000));
#endif
	INIT_DELAYED_WORK(&usbsw->audio_work, fsa9485_delayed_audio);
	schedule_delayed_work(&usbsw->audio_work, msecs_to_jiffies(20000));
#if defined(CONFIG_VIDEO_MHL_V1) || defined(CONFIG_VIDEO_MHL_V2)
	INIT_DELAYED_WORK(&usbsw->mhl_work, fsa9485_mhl_detect);
#endif
	return 0;
err_create_file_reset_switch:
	device_remove_file(switch_dev, &dev_attr_reset_switch);
err_create_file_adc:
	device_remove_file(switch_dev, &dev_attr_adc);
err_create_file_state:
	device_remove_file(switch_dev, &dev_attr_usb_state);
fail2:
	if (client->irq)
		free_irq(client->irq, usbsw);
fail1:
	input_unregister_device(input);
	mutex_destroy(&usbsw->mutex);
	i2c_set_clientdata(client, NULL);
	input_free_device(input);
	kfree(usbsw);
	return ret;
}
Exemplo n.º 6
0
static int __devinit fsa9485_probe(struct i2c_client *client,
			 const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct fsa9485_usbsw *usbsw;
	int ret = 0;
	struct device *switch_dev;

	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EIO;

	usbsw = kzalloc(sizeof(struct fsa9485_usbsw), GFP_KERNEL);
	if (!usbsw) {
		dev_err(&client->dev, "failed to allocate driver data\n");
		kfree(usbsw);
		return -ENOMEM;
	}

	usbsw->client = client;
	usbsw->pdata = client->dev.platform_data;
	if (!usbsw->pdata)
		goto fail1;

	i2c_set_clientdata(client, usbsw);

	mutex_init(&usbsw->mutex);

	local_usbsw = usbsw;

	fsa9485_reg_init(usbsw);

	ret = sysfs_create_group(&client->dev.kobj, &fsa9485_group);
	if (ret) {
		dev_err(&client->dev,
				"failed to create fsa9485 attribute group\n");
		goto fail2;
	}

	/* make sysfs node /sys/class/sec/switch/usb_state */
	switch_dev = device_create(sec_class, NULL, 0, NULL, "switch");
	if (IS_ERR(switch_dev)) {
		pr_err("[FSA9485] Failed to create device (switch_dev)!\n");
		ret = PTR_ERR(switch_dev);
		goto fail2;
	}

	ret = device_create_file(switch_dev, &dev_attr_usb_state);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (usb_state)!\n");
		goto err_create_file_state;
	}

	ret = device_create_file(switch_dev, &dev_attr_adc);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (adc)!\n");
		goto err_create_file_adc;
	}

	ret = device_create_file(switch_dev, &dev_attr_reset_switch);
	if (ret < 0) {
		pr_err("[FSA9485] Failed to create file (reset_switch)!\n");
		goto err_create_file_reset_switch;
	}

	dev_set_drvdata(switch_dev, usbsw);
	/* fsa9485 dock init*/
	if (usbsw->pdata->dock_init)
		usbsw->pdata->dock_init();

	/* initial cable detection */
	INIT_DELAYED_WORK(&usbsw->init_work, fsa9485_init_detect);
	schedule_delayed_work(&usbsw->init_work, msecs_to_jiffies(2700));

	return 0;

err_create_file_reset_switch:
	device_remove_file(switch_dev, &dev_attr_reset_switch);
err_create_file_adc:
	device_remove_file(switch_dev, &dev_attr_adc);
err_create_file_state:
	device_remove_file(switch_dev, &dev_attr_usb_state);
fail2:
	if (client->irq)
		free_irq(client->irq, usbsw);
fail1:
	mutex_destroy(&usbsw->mutex);
	i2c_set_clientdata(client, NULL);
	kfree(usbsw);
	return ret;
}