static int smb345_inok_irq(struct smb345_charger *smb)
{
	int err = 0 ;
	unsigned gpio = GPIO_AC_OK;
	unsigned irq_num = gpio_to_irq(gpio);

	err = gpio_request(gpio, "smb345_inok");
	if (err) {
		SMB_ERR("gpio %d request failed \n", gpio);
	}

	err = gpio_direction_input(gpio);
	if (err) {
		SMB_ERR("gpio %d unavaliable for input \n", gpio);
	}

	err = request_irq(irq_num, smb345_inok_isr, IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING|IRQF_SHARED,
		"smb345_inok", smb);
	if (err < 0) {
		SMB_ERR("%s irq %d request failed \n","smb345_inok", irq_num);
		goto fault ;
	}
	enable_irq_wake(irq_num);
	SMB_NOTICE("GPIO pin irq %d requested ok, smb345_INOK = %s\n", irq_num, gpio_get_value(gpio)? "H":"L");
	return 0;

fault:
	gpio_free(gpio);
	return err;
}
int smb345_float_volt_set(unsigned int val)
{
	struct i2c_client *client = charger->client;
	int ret = 0, retval;

	if (val > 4500 || val < 3500) {
		SMB_ERR("%s(): val=%d is out of range !\n",__func__, val);
	}

	printk("%s(): val=%d\n",__func__, val);

	ret = smb345_volatile_writes(client, smb345_ENABLE_WRITE);
	if (ret < 0) {
		dev_err(&client->dev, "%s() charger enable write error..\n", __func__);
		goto fault;
	}

	retval = smb345_read(client, smb345_FLOAT_VLTG);
	if (retval < 0) {
		dev_err(&client->dev, "%s(): Failed in reading 0x%02x",
				__func__, smb345_FLOAT_VLTG);
		goto fault;
	}
	retval = retval & (~FLOAT_VOLT_MASK);
	val = clamp_val(val, 3500, 4500) - 3500;
	val /= 20;
	retval |= val;
	ret = smb345_write(client, smb345_FLOAT_VLTG, retval);
	if (ret < 0) {
		dev_err(&client->dev, "%s(): Failed in writing"
			"register 0x%02x\n", __func__, smb345_FLOAT_VLTG);
		goto fault;
       }

	ret = smb345_volatile_writes(client, smb345_DISABLE_WRITE);
	if (ret < 0) {
		dev_err(&client->dev, "%s() charger disable write error..\n", __func__);
	}
	return 0;
fault:
	return ret;
}
Example #3
0
/* Sysfs function */
static ssize_t smb347_reg_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct i2c_client *client = charger->client;
	uint8_t config_reg[14], cmd_reg[1], status_reg[10];
	int i, ret = 0;

	ret += i2c_smbus_read_i2c_block_data(client, smb347_CHARGE, 15, config_reg)
	     + i2c_smbus_read_i2c_block_data(client, smb347_CMD_REG, 2, cmd_reg)
	     + i2c_smbus_read_i2c_block_data(client, smb347_INTR_STS_A, 11, status_reg);

	if (ret < 0)
		SMB_ERR("failed to read charger reg !\n");

	SMB_INFO("smb347 Registers\n");
	SMB_INFO("------------------\n");
	for(i=0;i<=14;i++)
		SMB_INFO("Reg[%02xh]=0x%02x\n", i, config_reg[i]);
	for(i=0;i<=1;i++)
		SMB_INFO("Reg[%02xh]=0x%02x\n", 48+i, cmd_reg[i]);
	for(i=0;i<=10;i++)
		SMB_INFO("Reg[%02xh]=0x%02x\n", 53+i, status_reg[i]);

	return sprintf(buf, "Reg[06h]=0x%02x\n"
		"Reg[08h]=0x%02x\n"
		"Reg[30h]=0x%02x\n"
		"Reg[31h]=0x%02x\n"
		"Reg[39h]=0x%02x\n"
		"Reg[3dh]=0x%02x\n"
		"Reg[3eh]=0x%02x\n"
		"Reg[3fh]=0x%02x\n",
		config_reg[6],
		config_reg[8],
		cmd_reg[0],
		cmd_reg[1],
		status_reg[4],
		status_reg[8],
		status_reg[9],
		status_reg[10]);

}
static int __devinit smb345_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
	struct smb345_platform_data *platform_data;
	int ret;

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

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

	printk("smb345_probe+\n");
	charger->client = client;
	charger->dev = &client->dev;
	i2c_set_clientdata(client, charger);

	smb345_otg_setting(charger->client);

	ret = sysfs_create_group(&client->dev.kobj, &smb345_group);
	if (ret) {
		SMB_ERR("Unable to create the sysfs\n");
		goto error;
	}

	mutex_init(&charger->apsd_lock);
	mutex_init(&charger->usb_lock);
	mutex_init(&charger->pinctrl_lock);

	smb345_wq = create_singlethread_workqueue("smb345_wq");

	INIT_DELAYED_WORK_DEFERRABLE(&charger->wireless_isr_work,
		wireless_isr_work_function);
	INIT_DELAYED_WORK_DEFERRABLE(&charger->wireless_det_work,
		wireless_det_work_function);
	INIT_DELAYED_WORK_DEFERRABLE(&charger->wireless_set_current_work,
		wireless_set_current_function);
	INIT_DELAYED_WORK_DEFERRABLE(&charger->cable_det_work,
		cable_det_work_function);

	wake_lock_init(&charger_wakelock, WAKE_LOCK_SUSPEND,
			"charger_configuration");
	wake_lock_init(&wireless_wakelock, WAKE_LOCK_SUSPEND,
			"wireless_charger");
	charger->curr_limit = UINT_MAX;
	charger->wpc_curr_limit = 300;
	charger->wpc_curr_limit_count = 0;
	charger->cur_cable_type = non_cable;
	charger->old_cable_type = non_cable;
	charger->wpc_pok_gpio = -1;
	charger->wpc_en1 = -1;
	charger->wpc_en2 = -1;
	wireless_on = false;
	otg_on = false;
	wpc_en = false;
	disable_DCIN = false;

	ret = smb345_inok_irq(charger);
	if (ret) {
		SMB_ERR("Failed in requesting ACOK# pin isr\n");
		goto error;
	}

	if (client->dev.platform_data) {
		platform_data = client->dev.platform_data;
		if (platform_data->wpc_pok_gpio != -1) {
			charger->wpc_pok_gpio = platform_data->wpc_pok_gpio;
			ret = smb345_wireless_irq(charger);
			if (ret) {
				SMB_ERR("Failed in requesting WPC_POK# pin isr\n");
				goto error;
			}

		}
		if (platform_data->wpc_en1 != -1 && platform_data->wpc_en2 != -1) {
			charger->wpc_en1 = platform_data->wpc_en1;
			charger->wpc_en2 = platform_data->wpc_en2;
			wpc_en = true;
			ret = smb345_wireless_en_config(charger);
			if (ret) {
				SMB_ERR("Failed in config WPC en gpio\n");
				goto error;
			}
		}
		queue_delayed_work(smb345_wq, &charger->wireless_det_work, WPC_INIT_DET_INTERVAL);
	}

	printk("smb345_probe-\n");

	return 0;
error:
	kfree(charger);
	return ret;
}