Esempio n. 1
0
static int write_muic_ctrl_reg(struct max14577_muic_data *muic_data,
				const u8 reg, const u8 val)
{
	struct i2c_client *i2c = muic_data->i2c;
	int ret = 0;
	u8 reg_val = 0;

	ret = max14577_read_reg(i2c, reg, &reg_val);
	if (ret < 0)
		pr_err("%s:%s err read REG(0x%02x) [%d]\n", MUIC_DEV_NAME,
				__func__, reg, ret);

	if (reg_val ^ val) {
		pr_info("%s:%s overwrite REG(0x%02x) from [0x%x] to [0x%x]\n",
				MUIC_DEV_NAME, __func__, reg, reg_val, val);

		ret = max14577_write_reg(i2c, reg, val);
		if (ret < 0)
			pr_err("%s:%s err write REG(0x%02x)\n", MUIC_DEV_NAME,
					__func__, reg);
	} else {
		pr_info("%s:%s REG(0x%02x) already [0x%x], just return\n",
				MUIC_DEV_NAME, __func__, reg, reg_val);
	}

	ret = max14577_read_reg(i2c, reg, &reg_val);
	if (ret < 0)
		pr_err("%s:%s err read REG(0x%02x) [%d]\n", MUIC_DEV_NAME,
				__func__, reg, ret);
	else
		pr_info("%s:%s REG(0x%02x) after change [0x%x]\n", MUIC_DEV_NAME,
				__func__, reg, reg_val);

	return ret;
}
Esempio n. 2
0
static void max14577_muic_set_adcdbset(struct max14577_muic_data *muic_data,
					int value)
{
	int ret;
	u8 val;
	u8 cntl3_before, cntl3_after;

	if (value > 3) {
		pr_err("%s:%s invalid value(%d)\n", MUIC_DEV_NAME, __func__,
				value);
		return;
	}

	if (!muic_data->i2c) {
		pr_err("%s:%s no muic i2c client\n", MUIC_DEV_NAME, __func__);
		return;
	}

	val = (value << CTRL3_ADCDBSET_SHIFT);
	max14577_read_reg(muic_data->i2c, MAX14577_MUIC_REG_CONTROL3,
			&cntl3_before);

	ret = max14577_write_reg(muic_data->i2c, MAX14577_MUIC_REG_CONTROL3,
			val);
	if (ret < 0)
		pr_err("%s: fail to write reg\n", __func__);

	max14577_read_reg(muic_data->i2c, MAX14577_MUIC_REG_CONTROL3,
			&cntl3_after);

	pr_info("%s:%s CNTL3: before(0x%02x), value(0x%02x), after(0x%02x)\n",
			MUIC_DEV_NAME, __func__, cntl3_before, val, cntl3_after);
}
Esempio n. 3
0
static void max14577_read_regs(struct sec_charger_info *charger, char *str)
{
	u8 data = 0;
	u32 addr = 0;

	max14577_read_reg(charger->client, MAX14577_CHG_REG_STATUS3, &data);
	sprintf(str+strlen(str), "0x%x, ", data);

	for (addr = MAX14577_CHG_REG_CHG_CTRL1;
		addr <= MAX14577_CHG_REG_CHG_CTRL7; addr++) {
		max14577_read_reg(charger->client, addr, &data);
		sprintf(str+strlen(str), "0x%x, ", data);
	}
}
static ssize_t max14577_muic_show_manual_sw(struct device *dev,
						   struct device_attribute *attr, char *buf)
{
	struct max14577_muic_data *muic_data = dev_get_drvdata(dev);
	u8 val = 0;
	ssize_t cnt = 0;

	max14577_read_reg(muic_data->i2c, MAX14577_MUIC_REG_CONTROL1, &val);

	switch (val) {
		case 0x9:
			cnt = sprintf(buf, "USB\n");
			break;
		case 0x12:
			cnt = sprintf(buf, "AUDIO\n");
			break;
		case 0x1b:
			cnt = sprintf(buf, "UART\n");
			break;
		default:
			cnt = sprintf(buf, "OPEN\n");
			break;
	}

	return cnt;
}
Esempio n. 5
0
static int max14577_get_charging_status(struct sec_charger_info *charger)
{
	int status = POWER_SUPPLY_STATUS_UNKNOWN;
	u8 data = 0;

	max14577_read_reg(charger->client, MAX14577_CHG_REG_STATUS3, &data);
	dev_info(&charger->client->dev,
		"%s : charger status (0x%02x)\n", __func__, data);

	if (data & 0x01) {
		status = POWER_SUPPLY_STATUS_FULL;
		data = 0;
		max14577_set_command(charger, MAX14577_CHG_REG_CHG_CTRL6, data);
	}
	else if (data & 0x02)
		status = POWER_SUPPLY_STATUS_CHARGING;
	else if (data & 0x04)
		status = POWER_SUPPLY_STATUS_NOT_CHARGING;
	else
		status = POWER_SUPPLY_STATUS_DISCHARGING;
#if 0
	max14577_test_read_regs(charger);
#endif
	return (int)status;
}
Esempio n. 6
0
static void max14577_test_read_regs(struct sec_charger_info *charger)
{
    u8 data = 0;
    u32 addr = 0;

    max14577_read_reg(charger->client, MAX14577_CHG_REG_STATUS3, &data);
    dev_info(&charger->client->dev, "%s : 0x%02x (0x%02x)\n",
             __func__, MAX14577_CHG_REG_STATUS3, data);

    for (addr = MAX14577_CHG_REG_CHG_CTRL1;
            addr <= MAX14577_CHG_REG_CHG_CTRL7; addr++) {
        max14577_read_reg(charger->client, addr, &data);
        dev_info(&charger->client->dev, "%s : 0x%02x (0x%02x)\n",
                 __func__, addr, data);
    }
}
Esempio n. 7
0
static void max14577_set_command(struct sec_charger_info *charger,
				int reg, int datum)
{
	int val;
	u8 data = 0;
	val = max14577_read_reg(charger->client, (u8)reg, &data);
	if (val >= 0) {
		dev_dbg(&charger->client->dev, "%s : reg(0x%02x): 0x%02x",
			__func__, reg, data);
		if (data != datum) {
			data = datum;
			if (max14577_write_reg(charger->client,
				(u8)reg, data) < 0)
				dev_err(&charger->client->dev,
					"%s : error!\n", __func__);
			val = max14577_read_reg(charger->client,
				(u8)reg, &data);
			if (val >= 0)
				dev_dbg(&charger->client->dev,
					" => 0x%02x\n", data);
		}
	}
}
Esempio n. 8
0
int max14577_get_control2_reg(struct i2c_client *i2c, u8 *val)
{
	u8 value = 0;
	int ret = 0;

	ret = max14577_read_reg(i2c, MAX14577_REG_CONTROL2, &value);
	if (ret)
		*val = 0xff;
	else
		*val = value;

	pr_info("%s:%s(0x%02x), ret(%d)\n", MFD_DEV_NAME, __func__, *val, ret);

	return ret;
}
Esempio n. 9
0
static u8 max14577_muic_get_adc_value(struct max14577_muic_data *muic_data)
{
	u8 status;
	u8 adc = ADC_ERROR;
	int ret = 0;

	ret = max14577_read_reg(muic_data->i2c, MAX14577_MUIC_REG_STATUS1,
			&status);
	if (ret)
		pr_err("%s:%s fail to read muic reg(%d)\n", MUIC_DEV_NAME,
				__func__, ret);
	else
		adc = status & STATUS1_ADC_MASK;

	return adc;
}
Esempio n. 10
0
static int max14577_get_charging_health(struct sec_charger_info *charger)
{
    int health = POWER_SUPPLY_HEALTH_GOOD;
    u8 data = 0;

    max14577_read_reg(charger->client, MAX14577_CHG_REG_STATUS3, &data);
    dev_info(&charger->client->dev,
             "%s : charger status (0x%02x)\n", __func__, data);

    if (data & 0x04)
        health = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
    else
        health = POWER_SUPPLY_HEALTH_GOOD;

    return (int)health;
}
Esempio n. 11
0
bool sec_hal_chg_get_property(struct sec_charger_info *charger,
                              enum power_supply_property psp,
                              union power_supply_propval *val)
{
    u8 data;

    switch (psp) {
    case POWER_SUPPLY_PROP_STATUS:
        val->intval = max14577_get_charging_status(charger);
        break;

    case POWER_SUPPLY_PROP_CHARGE_TYPE:
        if (charger->is_charging)
            val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
        else
            val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
        break;

    case POWER_SUPPLY_PROP_HEALTH:
        val->intval = max14577_get_charging_health(charger);
        break;
    case POWER_SUPPLY_PROP_ONLINE:
        val->intval = charger->cable_type;
        break;
    case POWER_SUPPLY_PROP_CURRENT_AVG:	/* charging current */
    /* calculated input current limit value */
    case POWER_SUPPLY_PROP_CURRENT_NOW:
        if (charger->charging_current) {
            max14577_read_reg(charger->client,
                              MAX14577_CHG_REG_CHG_CTRL4, &data);
            if (data & 0x10) /* enable fast charge current set */
                val->intval = (data & 0x0f) * 50 + 200;
            else
                val->intval = 90;
        } else
            val->intval = 0;

        dev_dbg(&charger->client->dev,
                "%s : set-current(%dmA), current now(%dmA)\n",
                __func__, charger->charging_current, val->intval);
        break;
    default:
        return false;
    }
    return true;
}
Esempio n. 12
0
ssize_t sec_hal_chg_store_attrs(struct device *dev,
                                const ptrdiff_t offset,
                                const char *buf, size_t count)
{
    struct power_supply *psy = dev_get_drvdata(dev);
    struct sec_charger_info *chg =
        container_of(psy, struct sec_charger_info, psy_chg);
    int ret = 0;
    int x = 0;
    u8 data = 0;

    switch (offset) {
    case CHG_REG:
        if (sscanf(buf, "%x\n", &x) == 1) {
            chg->reg_addr = x;
            max14577_read_reg(chg->client,
                              chg->reg_addr, &data);
            chg->reg_data = data;
            dev_dbg(dev, "%s: (read) addr = 0x%x, data = 0x%x\n",
                    __func__, chg->reg_addr, chg->reg_data);
            ret = count;
        }
        break;
    case CHG_DATA:
        if (sscanf(buf, "%x\n", &x) == 1) {
            data = (u8)x;
            dev_dbg(dev, "%s: (write) addr = 0x%x, data = 0x%x\n",
                    __func__, chg->reg_addr, data);
            max14577_write_reg(chg->client,
                               chg->reg_addr, data);
            ret = count;
        }
        break;
    default:
        ret = -EINVAL;
        break;
    }

    return ret;
}
Esempio n. 13
0
bool sec_hal_chg_get_property(struct sec_charger_info *charger,
			      enum power_supply_property psp,
			      union power_supply_propval *val)
{
	u8 data;

	switch (psp) {
	case POWER_SUPPLY_PROP_STATUS:
		val->intval = max14577_get_charging_status(charger);
		break;

	case POWER_SUPPLY_PROP_CHARGE_TYPE:
		if (charger->is_charging)
			val->intval = POWER_SUPPLY_CHARGE_TYPE_FAST;
		else
			val->intval = POWER_SUPPLY_CHARGE_TYPE_NONE;
		break;

	case POWER_SUPPLY_PROP_HEALTH:
		val->intval = max14577_get_charging_health(charger);
		break;
	case POWER_SUPPLY_PROP_ONLINE:
		val->intval = charger->cable_type;
		break;
	case POWER_SUPPLY_PROP_CURRENT_AVG:	/* charging current */
	/* calculated input current limit value */
	case POWER_SUPPLY_PROP_CURRENT_NOW:
		if (charger->charging_current) {
			max14577_read_reg(charger->client,
				MAX14577_CHG_REG_CHG_CTRL4, &data);
			if (data & 0x10) /* enable fast charge current set */
#if defined(max77836_charger)
				val->intval = (data & 0x0f) * 25 + 100;
#else
				val->intval = (data & 0x0f) * 50 + 200;
#endif
			else
				val->intval = 90;
		} else
Esempio n. 14
0
void max14577_muic_shutdown(struct device *dev)
{
	struct max14577_muic_data *muic_data = dev_get_drvdata(dev);
	struct max14577_dev *max14577;
	int ret;
	u8 val;
	u8 ctrl2 = 0;

	pr_info("%s:%s +\n", MUIC_DEV_NAME, __func__);
	if (!muic_data->i2c) {
		pr_err("%s:%s no muic i2c client\n", MUIC_DEV_NAME, __func__);
		return;
	}

	max14577 = i2c_get_clientdata(muic_data->i2c);
	pr_info("%s:%s max14577->i2c_lock.count.counter=%d\n", MUIC_DEV_NAME,
		__func__, max14577->i2c_lock.count.counter);

	pr_info("%s:%s JIGSet: auto detection\n", MUIC_DEV_NAME, __func__);
	val = (0 << CTRL3_JIGSET_SHIFT) | (0 << CTRL3_BOOTSET_SHIFT);

	ret = max14577_update_reg(muic_data->i2c, MAX14577_MUIC_REG_CONTROL3,
			val, CTRL3_JIGSET_MASK | CTRL3_BOOTSET_MASK);
	if (ret < 0) {
		pr_err("%s:%s fail to update reg\n", MUIC_DEV_NAME, __func__);
		return;
	}

	ret = max14577_read_reg(muic_data->i2c, MAX14577_REG_CONTROL2, &ctrl2);
	if (ret) {
		pr_err("%s:%s fail to read cntl2 reg\n", MUIC_DEV_NAME, __func__);
		return;
	}
	pr_info("%s:%s: ctrl2:0x%x\n", MUIC_DEV_NAME, __func__, ctrl2);
	pr_info("%s:%s -\n", MUIC_DEV_NAME, __func__);
}
Esempio n. 15
0
int max14577_irq_init(struct max14577_dev *max14577)
{
	struct max14577_platform_data *pdata = max14577->pdata;
	struct i2c_client *i2c = max14577->i2c;
	int i;
	int cur_irq;
	int ret;
	u8 val;

	if (!pdata->irq_gpio) {
		pr_warn("%s:%s No interrupt specified.\n", MFD_DEV_NAME,
				__func__);
		pdata->irq_base = 0;
		return 0;
	}

	if (!pdata->irq_base) {
		pr_err("%s:%s No interrupt base specified.\n", MFD_DEV_NAME,
				__func__);
		return 0;
	}

	mutex_init(&max14577->irq_lock);

	max14577->irq = gpio_to_irq(pdata->irq_gpio);
	ret = gpio_request(pdata->irq_gpio, "max14577_irq");
	if (ret) {
		pr_err("%s:%s failed requesting gpio(%d)\n", MFD_DEV_NAME,
			__func__, pdata->irq_gpio);
		return ret;
	}
	gpio_direction_input(pdata->irq_gpio);
	gpio_free(pdata->irq_gpio);

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

	max14577_write_reg(max14577->i2c_pmic, MAX77836_PMIC_REG_INTSRC_MASK, 0xF7);
	max14577_read_reg(max14577->i2c_pmic, MAX77836_PMIC_REG_INTSRC_MASK, &val);
	pr_info("%s: INTSRC:0x%x\n", __func__, val);

	/* Mask individual interrupt sources */
	for (i = 0; i < MAX14577_IRQ_REGS_NUM; i++) {
		/* IRQ  0:MASK 1:NOT MASK */
		max14577->irq_masks_cur[i] = 0x00;
		max14577->irq_masks_cache[i] = 0x00;

		if (IS_ERR_OR_NULL(i2c))
			continue;
		if (max14577_mask_reg[i] == MAX14577_REG_INVALID)
			continue;

		max14577_write_reg(i2c, max14577_mask_reg[i],
				max14577->irq_masks_cur[i]);
	}

	/* Register with genirq */
	for (i = 0; i < MAX14577_IRQ_NUM; i++) {
		cur_irq = i + pdata->irq_base;
		ret = irq_set_chip_data(cur_irq, max14577);
		if (ret) {
			pr_err("%s: Failed to set_chip_data (irq:%d, ret:%d)\n",
				__func__, cur_irq, ret);
			continue;
		}

		irq_set_chip_and_handler(cur_irq, &max14577_irq_chip, handle_edge_irq);
		irq_set_nested_thread(cur_irq, true);
#ifdef CONFIG_ARM
		set_irq_flags(cur_irq, IRQF_VALID);
#else
		irq_set_noprobe(cur_irq);
#endif
	}

	ret = request_threaded_irq(max14577->irq, NULL, max14577_irq_thread,
				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
				   "max14577-irq", max14577);
	if (ret) {
		pr_err("%s:%s Failed to request IRQ(%d) ret(%d)\n",
				MFD_DEV_NAME, __func__, max14577->irq, ret);
		return ret;
	}

	return 0;
}
Esempio n. 16
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;
}
Esempio n. 17
0
static void max14577_muic_detect_dev(struct max14577_muic_data *muic_data, int irq)
{
	struct i2c_client *i2c = muic_data->i2c;
	const struct max14577_muic_vps_data *tmp_vps;
	enum muic_attached_dev new_dev = ATTACHED_DEV_UNKNOWN_MUIC;
	int intr = MUIC_INTR_DETACH;
	u8 status[2], ctrl2, ctrl3;
	u8 adcerr, adclow, adc, vbvolt, chgdetrun, chgtyp, adcen;
	int ret;
	int i;

	ret = max14577_bulk_read(i2c, MAX14577_MUIC_REG_STATUS1, 2, status);
	if (ret) {
		pr_err("%s:%s fail to read STAT (%d)\n", MUIC_DEV_NAME,	__func__, ret);
		return;
	}

	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);
		return;
	}

	ret = max14577_read_reg(muic_data->i2c, MAX14577_MUIC_REG_CONTROL3, &ctrl3);
	if (ret) {
		pr_err("%s:%s fail to read CTRL3 (%d)\n", MUIC_DEV_NAME, __func__, ret);
		return;
	}

	pr_info("%s:%s STATUS1:0x%02x, 2:0x%02x, ctrl2:0x%02x\n", MUIC_DEV_NAME,
		__func__, status[0], status[1], ctrl2);

	adcerr = status[0] & STATUS1_ADCERR_MASK;
	adclow = status[0] & STATUS1_ADCLOW_MASK;
	adc = status[0] & STATUS1_ADC_MASK;
	vbvolt = status[1] & STATUS2_VBVOLT_MASK;
	chgdetrun = status[1] & STATUS2_CHGDETRUN_MASK;
	chgtyp = status[1] & STATUS2_CHGTYP_MASK;
	adcen = ctrl2 & CTRL2_ADCEN_MASK;

	pr_info("%s:%s adcerr:0x%x adclow:0x%x adc:0x%x vb:0x%x chgdetrun:0x%x"
			" chgtyp:0x%x adcen:0x%x\n", MUIC_DEV_NAME, __func__, adcerr,
			adclow, adc, vbvolt, chgdetrun, chgtyp, adcen);

	/* Workaround for Factory mode.
	 * Abandon adc interrupt of approximately +-100K range
	 * if previous cable status was JIG UART BOOT OFF.
	 */
	if (muic_data->attached_dev == ATTACHED_DEV_JIG_UART_OFF_MUIC) {
		if ((adc == (ADC_JIG_UART_OFF + 1)) ||
				(adc == (ADC_JIG_UART_OFF - 1))) {
			pr_warn("%s:%s abandon ADC\n", MUIC_DEV_NAME, __func__);
			return;
		}
	}

	for (i = 0; i < ARRAY_SIZE(muic_vps_table); i++) {
		tmp_vps = &(muic_vps_table[i]);

		if (tmp_vps->adcerr != adcerr)
			continue;

		if (tmp_vps->adclow != adclow)
			continue;

		if (tmp_vps->adc != adc)
			continue;

		if (tmp_vps->vbvolt != vbvolt)
			continue;

		if (tmp_vps->chgdetrun != chgdetrun)
			continue;

		if (tmp_vps->chgtyp != chgtyp)
			continue;

		pr_info("%s:%s vps table match found at i(%d), %s\n",
				MUIC_DEV_NAME, __func__, i, tmp_vps->vps_name);

		new_dev = tmp_vps->attached_dev;

		intr = MUIC_INTR_ATTACH;
		break;
	}

	if (intr == MUIC_INTR_ATTACH) {
		pr_info("%s:%s ATTACHED\n", MUIC_DEV_NAME, __func__);
		max14577_muic_handle_attach(muic_data, new_dev);
	} else {
		pr_info("%s:%s DETACHED\n", MUIC_DEV_NAME, __func__);
		max14577_muic_handle_detach(muic_data);
	}
	return;
}
Esempio n. 18
0
static int max14577_muic_probe(struct platform_device *pdev)
{
	struct max14577 *max14577 = dev_get_drvdata(pdev->dev.parent);
	struct max14577_muic_info *info;
	int delay_jiffies;
	int ret;
	int i;
	u8 id;

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

	info->dev = &pdev->dev;
	info->max14577 = max14577;

	platform_set_drvdata(pdev, info);
	mutex_init(&info->mutex);

	INIT_WORK(&info->irq_work, max14577_muic_irq_work);

	switch (max14577->dev_type) {
	case MAXIM_DEVICE_TYPE_MAX77836:
		info->muic_irqs = max77836_muic_irqs;
		info->muic_irqs_num = ARRAY_SIZE(max77836_muic_irqs);
		break;
	case MAXIM_DEVICE_TYPE_MAX14577:
	default:
		info->muic_irqs = max14577_muic_irqs;
		info->muic_irqs_num = ARRAY_SIZE(max14577_muic_irqs);
	}

	/* Support irq domain for max14577 MUIC device */
	for (i = 0; i < info->muic_irqs_num; i++) {
		struct max14577_muic_irq *muic_irq = &info->muic_irqs[i];
		int virq = 0;

		virq = regmap_irq_get_virq(max14577->irq_data, muic_irq->irq);
		if (virq <= 0)
			return -EINVAL;
		muic_irq->virq = virq;

		ret = devm_request_threaded_irq(&pdev->dev, virq, NULL,
				max14577_muic_irq_handler,
				IRQF_NO_SUSPEND,
				muic_irq->name, info);
		if (ret) {
			dev_err(&pdev->dev,
				"failed: irq request (IRQ: %d, error :%d)\n",
				muic_irq->irq, ret);
			return ret;
		}
	}

	/* Initialize extcon device */
	info->edev = devm_extcon_dev_allocate(&pdev->dev,
					      max14577_extcon_cable);
	if (IS_ERR(info->edev)) {
		dev_err(&pdev->dev, "failed to allocate memory for extcon\n");
		return -ENOMEM;
	}

	ret = devm_extcon_dev_register(&pdev->dev, info->edev);
	if (ret) {
		dev_err(&pdev->dev, "failed to register extcon device\n");
		return ret;
	}

	/* Default h/w line path */
	info->path_usb = CTRL1_SW_USB;
	info->path_uart = CTRL1_SW_UART;
	delay_jiffies = msecs_to_jiffies(DELAY_MS_DEFAULT);

	/* Set initial path for UART */
	max14577_muic_set_path(info, info->path_uart, true);

	/* Check revision number of MUIC device*/
	ret = max14577_read_reg(info->max14577->regmap,
			MAX14577_REG_DEVICEID, &id);
	if (ret < 0) {
		dev_err(&pdev->dev, "failed to read revision number\n");
		return ret;
	}
	dev_info(info->dev, "device ID : 0x%x\n", id);

	/* Set ADC debounce time */
	max14577_muic_set_debounce_time(info, ADC_DEBOUNCE_TIME_25MS);

	/*
	 * Detect accessory after completing the initialization of platform
	 *
	 * - Use delayed workqueue to detect cable state and then
	 * notify cable state to notifiee/platform through uevent.
	 * After completing the booting of platform, the extcon provider
	 * driver should notify cable state to upper layer.
	 */
	INIT_DELAYED_WORK(&info->wq_detcable, max14577_muic_detect_cable_wq);
	queue_delayed_work(system_power_efficient_wq, &info->wq_detcable,
			delay_jiffies);

	return ret;
}
Esempio n. 19
0
static int max14577_i2c_probe(struct i2c_client *i2c,
			      const struct i2c_device_id *id)
{
	struct max14577 *max14577;
	struct max14577_platform_data *pdata = dev_get_platdata(&i2c->dev);
	struct device_node *np = i2c->dev.of_node;
	u8 reg_data;
	int ret = 0;

	if (np) {
		pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
		if (!pdata)
			return -ENOMEM;
		i2c->dev.platform_data = pdata;
	}

	if (!pdata) {
		dev_err(&i2c->dev, "No platform data found.\n");
		return -EINVAL;
	}

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

	i2c_set_clientdata(i2c, max14577);
	max14577->dev = &i2c->dev;
	max14577->i2c = i2c;
	max14577->irq = i2c->irq;

	max14577->regmap = devm_regmap_init_i2c(i2c, &max14577_regmap_config);
	if (IS_ERR(max14577->regmap)) {
		ret = PTR_ERR(max14577->regmap);
		dev_err(max14577->dev, "Failed to allocate register map: %d\n",
				ret);
		return ret;
	}

	ret = max14577_read_reg(max14577->regmap, MAX14577_REG_DEVICEID,
			&reg_data);
	if (ret) {
		dev_err(max14577->dev, "Device not found on this channel: %d\n",
				ret);
		return ret;
	}
	max14577->vendor_id = ((reg_data & DEVID_VENDORID_MASK) >>
				DEVID_VENDORID_SHIFT);
	max14577->device_id = ((reg_data & DEVID_DEVICEID_MASK) >>
				DEVID_DEVICEID_SHIFT);
	dev_info(max14577->dev, "Device ID: 0x%x, vendor: 0x%x\n",
			max14577->device_id, max14577->vendor_id);

	ret = regmap_add_irq_chip(max14577->regmap, max14577->irq,
				  IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 0,
				  &max14577_irq_chip,
				  &max14577->irq_data);
	if (ret != 0) {
		dev_err(&i2c->dev, "Failed to request IRQ %d: %d\n",
				max14577->irq, ret);
		return ret;
	}

	ret = mfd_add_devices(max14577->dev, -1, max14577_devs,
			ARRAY_SIZE(max14577_devs), NULL, 0,
			regmap_irq_get_domain(max14577->irq_data));
	if (ret < 0)
		goto err_mfd;

	device_init_wakeup(max14577->dev, 1);

	return 0;

err_mfd:
	regmap_del_irq_chip(max14577->irq, max14577->irq_data);

	return ret;
}
Esempio n. 20
0
static int max14577_i2c_probe(struct i2c_client *i2c,
			      const struct i2c_device_id *id)
{
	struct max14577_dev *max14577;
	struct max14577_platform_data *pdata = i2c->dev.platform_data;
	u8 reg_data;
	int ret = 0;

	max14577 = kzalloc(sizeof(struct max14577_dev), GFP_KERNEL);
	if (max14577 == NULL)
		return -ENOMEM;

	i2c_set_clientdata(i2c, max14577);
	max14577->dev = &i2c->dev;
	max14577->i2c = i2c;
	max14577->irq = i2c->irq;
	if (pdata) {
		max14577->pdata = pdata;
	} else {
		ret = -EIO;
		goto err;
	}
	pdata->set_cdetctrl1_reg = max14577_set_cdetctrl1_reg;
	pdata->get_cdetctrl1_reg = max14577_get_cdetctrl1_reg;
	pdata->set_control2_reg = max14577_set_control2_reg;
	pdata->get_control2_reg = max14577_get_control2_reg;

	mutex_init(&max14577->i2c_lock);

	ret = max14577_read_reg(i2c, MAX14577_REG_DEVICEID, &reg_data);
	if (ret < 0) {
		pr_err("%s:%s device not found on this channel(%d)\n",
				MFD_DEV_NAME, __func__, ret);
		goto err;
	} else {
		/* print Device Id */
		max14577->vendor_id = (reg_data & 0x7);
		max14577->device_id = ((reg_data & 0xF8) >> 0x3);
		pr_info("%s:%s device found: vendor=0x%x, device_id=0x%x\n",
				MFD_DEV_NAME, __func__, max14577->vendor_id,
				max14577->device_id);
	}

	ret = max14577_irq_init(max14577);
	if (ret < 0)
		goto err;

	ret = mfd_add_devices(max14577->dev, -1, max14577_devs,
			ARRAY_SIZE(max14577_devs), NULL, 0);
	if (ret < 0)
		goto err_mfd;

	device_init_wakeup(max14577->dev, pdata->wakeup);

	return ret;

err_mfd:
	mfd_remove_devices(max14577->dev);
err:
	kfree(max14577);
	return ret;
}
Esempio n. 21
0
static int max14577_i2c_probe(struct i2c_client *i2c,
			      const struct i2c_device_id *id)
{
	struct max14577_dev *max14577;
	struct max14577_platform_data *pdata = NULL;
	u8 reg_data;
	int ret = 0;

	max14577 = kzalloc(sizeof(struct max14577_dev), GFP_KERNEL);
	if (max14577 == NULL)
		return -ENOMEM;

	if (i2c->dev.of_node) {
		pdata = devm_kzalloc(&i2c->dev,
				sizeof(struct max14577_platform_data),
				GFP_KERNEL);
		if (!pdata) {
			dev_err(&i2c->dev, "Failed to allocate memory\n");
			ret = -ENOMEM;
			goto err;
		}

		ret = of_max14577_dt(&i2c->dev, pdata);
		if (ret < 0) {
			dev_err(&i2c->dev, "Failed to get device of_node\n");
			kfree(pdata);
			goto err;
		}

		/*pdata update to other modules*/
		i2c->dev.platform_data = pdata;
	} else
		pdata = i2c->dev.platform_data;
	i2c_set_clientdata(i2c, max14577);
	max14577->dev = &i2c->dev;
	max14577->i2c = i2c;
	max14577->irq = i2c->irq;
	if (pdata) {
		max14577->pdata = pdata;
	} else {
		ret = -EIO;
		goto err;
	}
	pdata->set_cdetctrl1_reg = max14577_set_cdetctrl1_reg;
	pdata->get_cdetctrl1_reg = max14577_get_cdetctrl1_reg;
	pdata->set_control2_reg = max14577_set_control2_reg;
	pdata->get_control2_reg = max14577_get_control2_reg;
#ifdef CONFIG_REGULATOR_MAX77836
	pdata->regulators = max77836_reglator_pdata;
	pdata->num_regulators = MAX77836_LDO_MAX;
#endif
#ifdef CONFIG_CHARGER_MAX14577
	pdata->charger_data = &sec_battery_pdata;
#endif

	mutex_init(&max14577->i2c_lock);

	ret = max14577_read_reg(i2c, MAX14577_REG_DEVICEID, &reg_data);
	if (ret < 0) {
		pr_err("%s:%s device not found on this channel(%d)\n",
				MFD_DEV_NAME, __func__, ret);
		goto err;
	} else {
		/* print Device Id */
		max14577->vendor_id = (reg_data & 0x7);
		max14577->device_id = ((reg_data & 0xF8) >> 0x3);
		pr_info("%s:%s device found: vendor=0x%x, device_id=0x%x\n",
				MFD_DEV_NAME, __func__, max14577->vendor_id,
				max14577->device_id);
	}

	max14577->i2c_pmic = i2c_new_dummy(i2c->adapter, MAX77836_PMIC_ADDR);
		i2c_set_clientdata(max14577->i2c_pmic, max14577);

	ret = max14577_irq_init(max14577);
	if (ret < 0)
		goto err_irq_init;

	ret = mfd_add_devices(max14577->dev, -1, max14577_devs,
			ARRAY_SIZE(max14577_devs), NULL, 0);
	if (ret < 0)
		goto err_mfd;

	device_init_wakeup(max14577->dev, pdata->wakeup);

	return ret;

err_mfd:
	mfd_remove_devices(max14577->dev);
err_irq_init:
	if (max14577->i2c_pmic)
		i2c_unregister_device(max14577->i2c_pmic);
err:
	kfree(max14577);
	return ret;
}