예제 #1
0
static int bq27410_battery_probe(struct i2c_client *client,
				 const struct i2c_device_id *id)
{
	struct bq27410_device_info *di;
	int retval = 0;
	u8 buf[2];
	struct bq27410_platform_data *pdata;
	
	DBG("**********  bq27410_battery_probe**************  \n");
	
	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){
		client->addr = 0x0B;
		if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)){
			return -ENODEV;
		}
		else{
			g_bq27410_mode = BQ27410_ROM_MODE;
		}
	}
	else{
		g_bq27410_mode = BQ27410_NORMAL_MODE;
	}
	printk("+ g_bq27410_mode=%d \n", g_bq27410_mode);
	
	pdata = client->dev.platform_data;
	g_pdata = pdata;
	g_client = client;

	di = kzalloc(sizeof(*di), GFP_KERNEL);
	if (!di) {
		dev_err(&client->dev, "failed to allocate device info data\n");
		retval = -ENOMEM;
		goto batt_failed_2;
	}
	mutex_init(&g_bq27410_mutex);
		

	i2c_set_clientdata(client, di);
	di->dev = &client->dev;
	di->bat.name = "battery";
	di->client = client;
	/* 4 seconds between monotor runs interval */
	di->interval = msecs_to_jiffies(4 * 1000);
	
	di->bat_num = pdata->bat_num;
	di->dc_check_pin = pdata->dc_check_pin;
	di->bat_check_pin = pdata->bat_check_pin;
	di->wake_irq = pdata->low_power_pin;
	
	if (pdata->io_init)
		pdata->io_init();

	bq27410_di = di;

	retval = bq27410_read(client,0x00,buf,2);
	if(retval < 0){
		printk("failed to find bq27410\n");
		goto batt_failed_2;
	}else{
		rk30_bat_unregister();
		bq27410_init = 1;
	}

	//command batt insert.
	bq27410_write_batt_insert(client);
	battery_capacity_check(di);
	if(g_bq27410_mode == BQ27410_NORMAL_MODE){

//		if(!bq27410_read_control_status(client))
//		{
//			virtual_battery_enable = 1;

//			bq27410_powersupply_init(di);
//			retval = power_supply_register(&client->dev, &di->bat);

//			INIT_DELAYED_WORK(&di->update_work, bq27410_battery_update_work);
//			schedule_delayed_work(&di->update_work, msecs_to_jiffies(15 * 1000));
//		}
//		else{
			printk("NOT need bq27410_update_firmware \n");
			bq27410_powersupply_init(di);
			
			retval = power_supply_register(&client->dev, &di->bat);
			if (retval) {
				dev_err(&client->dev, "failed to register battery\n");
				goto batt_failed_4;
			}
			INIT_DELAYED_WORK(&di->work, bq27410_battery_work);
			schedule_delayed_work(&di->work, di->interval);
			dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
//		}
	}
	else
	{
		INIT_DELAYED_WORK(&di->update_work, bq27410_battery_update_work);
		schedule_delayed_work(&di->update_work, msecs_to_jiffies(15 * 1000));
	}
	printk("- g_bq27410_mode=%d \n", g_bq27410_mode);
	
	//M-MT:setup discharge/charge current threshold. 
	//bq27410_write_current_threshold(client);

	// battery low irq
	if(pdata->low_power_pin != INVALID_GPIO)
	{
		di->wake_irq = gpio_to_irq(pdata->low_power_pin);
		retval = request_irq(di->wake_irq, bq27410_bat_wakeup, IRQF_TRIGGER_FALLING, "bq27410_battery", di);
		if (retval) {
			printk("failed to request low_power_pin irq\n");
			goto err_batirq_failed;
		}
		
		INIT_DELAYED_WORK(&di->wakeup_work, bq27410_battery_wake_work);
		enable_irq_wake(di->wake_irq);
	}
	
	bq27410_proc_entry = create_proc_entry("bq27410-update", 0666, NULL);
	if(bq27410_proc_entry == NULL)
	{
		printk("Malata bq27410 Couldn't create proc entry!\n");
		return -ENOMEM;
	}
	else
	{
		printk("Malata bq27410 Create proc entry success!\n");
		bq27410_proc_entry->write_proc = bq27410_update_write;
		bq27410_proc_entry->read_proc = bq27410_update_read;
	}
	
	return 0;

batt_failed_4:
	kfree(di);
batt_failed_2:

err_batirq_failed:
	gpio_free(pdata->bat_check_pin);

	return retval;
}
static int msm_otg_suspend(struct msm_otg *motg)
{
	struct usb_phy *phy = &motg->phy;
	struct usb_bus *bus = phy->otg->host;
	struct msm_otg_platform_data *pdata = motg->pdata;
	void __iomem *addr;
	int cnt = 0;

	if (atomic_read(&motg->in_lpm))
		return 0;

	disable_irq(motg->irq);
	/*
	 * Chipidea 45-nm PHY suspend sequence:
	 *
	 * Interrupt Latch Register auto-clear feature is not present
	 * in all PHY versions. Latch register is clear on read type.
	 * Clear latch register to avoid spurious wakeup from
	 * low power mode (LPM).
	 *
	 * PHY comparators are disabled when PHY enters into low power
	 * mode (LPM). Keep PHY comparators ON in LPM only when we expect
	 * VBUS/Id notifications from USB PHY. Otherwise turn off USB
	 * PHY comparators. This save significant amount of power.
	 *
	 * PLL is not turned off when PHY enters into low power mode (LPM).
	 * Disable PLL for maximum power savings.
	 */

	if (motg->pdata->phy_type == CI_45NM_INTEGRATED_PHY) {
		ulpi_read(phy, 0x14);
		if (pdata->otg_control == OTG_PHY_CONTROL)
			ulpi_write(phy, 0x01, 0x30);
		ulpi_write(phy, 0x08, 0x09);
	}

	/*
	 * PHY may take some time or even fail to enter into low power
	 * mode (LPM). Hence poll for 500 msec and reset the PHY and link
	 * in failure case.
	 */
	writel(readl(USB_PORTSC) | PORTSC_PHCD, USB_PORTSC);
	while (cnt < PHY_SUSPEND_TIMEOUT_USEC) {
		if (readl(USB_PORTSC) & PORTSC_PHCD)
			break;
		udelay(1);
		cnt++;
	}

	if (cnt >= PHY_SUSPEND_TIMEOUT_USEC) {
		dev_err(phy->dev, "Unable to suspend PHY\n");
		msm_otg_reset(phy);
		enable_irq(motg->irq);
		return -ETIMEDOUT;
	}

	/*
	 * PHY has capability to generate interrupt asynchronously in low
	 * power mode (LPM). This interrupt is level triggered. So USB IRQ
	 * line must be disabled till async interrupt enable bit is cleared
	 * in USBCMD register. Assert STP (ULPI interface STOP signal) to
	 * block data communication from PHY.
	 */
	writel(readl(USB_USBCMD) | ASYNC_INTR_CTRL | ULPI_STP_CTRL, USB_USBCMD);

	addr = USB_PHY_CTRL;
	if (motg->phy_number)
		addr = USB_PHY_CTRL2;

	if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
			motg->pdata->otg_control == OTG_PMIC_CONTROL)
		writel(readl(addr) | PHY_RETEN, addr);

	clk_disable_unprepare(motg->pclk);
	clk_disable_unprepare(motg->clk);
	if (!IS_ERR(motg->core_clk))
		clk_disable_unprepare(motg->core_clk);

	if (motg->pdata->phy_type == SNPS_28NM_INTEGRATED_PHY &&
			motg->pdata->otg_control == OTG_PMIC_CONTROL) {
		msm_hsusb_ldo_set_mode(motg, 0);
		msm_hsusb_config_vddcx(motg, 0);
	}

	if (device_may_wakeup(phy->dev))
		enable_irq_wake(motg->irq);
	if (bus)
		clear_bit(HCD_FLAG_HW_ACCESSIBLE, &(bus_to_hcd(bus))->flags);

	atomic_set(&motg->in_lpm, 1);
	enable_irq(motg->irq);

	dev_info(phy->dev, "USB in low power mode\n");

	return 0;
}
예제 #3
0
/*
 * keypad controller should be initialized in the following sequence
 * only, otherwise it might get into FSM stuck state.
 *
 * - Initialize keypad control parameters, like no. of rows, columns,
 *   timing values etc.,
 * - configure rows and column gpios pull up/down.
 * - set irq edge type.
 * - enable the keypad controller.
 */
static int __devinit pmic8xxx_kp_probe(struct platform_device *pdev)
{
    const struct pm8xxx_keypad_platform_data *pdata =
        dev_get_platdata(&pdev->dev);
    const struct matrix_keymap_data *keymap_data;
    struct pmic8xxx_kp *kp;
    int rc;
    u8 ctrl_val;

    struct pm_gpio kypd_drv = {
        .direction	= PM_GPIO_DIR_OUT,
        .output_buffer	= PM_GPIO_OUT_BUF_OPEN_DRAIN,
        .output_value	= 0,
        .pull		= PM_GPIO_PULL_NO,
        .vin_sel	= PM_GPIO_VIN_S4,
        .out_strength	= PM_GPIO_STRENGTH_LOW,
        .function	= PM_GPIO_FUNC_1,
        .inv_int_pol	= 1,
    };

    struct pm_gpio kypd_sns = {
        .direction	= PM_GPIO_DIR_IN,
        .pull		= PM_GPIO_PULL_UP_31P5,
        .vin_sel	= PM_GPIO_VIN_S4,
        .out_strength	= PM_GPIO_STRENGTH_NO,
        .function	= PM_GPIO_FUNC_NORMAL,
        .inv_int_pol	= 1,
    };


    if (!pdata || !pdata->num_cols || !pdata->num_rows ||
            pdata->num_cols > PM8XXX_MAX_COLS ||
            pdata->num_rows > PM8XXX_MAX_ROWS ||
            pdata->num_cols < PM8XXX_MIN_COLS) {
        dev_err(&pdev->dev, "invalid platform data\n");
        return -EINVAL;
    }

    if (!pdata->scan_delay_ms ||
            pdata->scan_delay_ms > MAX_SCAN_DELAY ||
            pdata->scan_delay_ms < MIN_SCAN_DELAY ||
            !is_power_of_2(pdata->scan_delay_ms)) {
        dev_err(&pdev->dev, "invalid keypad scan time supplied\n");
        return -EINVAL;
    }

    if (!pdata->row_hold_ns ||
            pdata->row_hold_ns > MAX_ROW_HOLD_DELAY ||
            pdata->row_hold_ns < MIN_ROW_HOLD_DELAY ||
            ((pdata->row_hold_ns % MIN_ROW_HOLD_DELAY) != 0)) {
        dev_err(&pdev->dev, "invalid keypad row hold time supplied\n");
        return -EINVAL;
    }

    if (!pdata->debounce_ms ||
            ((pdata->debounce_ms % 5) != 0) ||
            pdata->debounce_ms > MAX_DEBOUNCE_TIME ||
            pdata->debounce_ms < MIN_DEBOUNCE_TIME) {
        dev_err(&pdev->dev, "invalid debounce time supplied\n");
        return -EINVAL;
    }

    keymap_data = pdata->keymap_data;
    if (!keymap_data) {
        dev_err(&pdev->dev, "no keymap data supplied\n");
        return -EINVAL;
    }

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

    platform_set_drvdata(pdev, kp);

    kp->pdata	= pdata;
    kp->dev		= &pdev->dev;

    kp->input = input_allocate_device();
    if (!kp->input) {
        dev_err(&pdev->dev, "unable to allocate input device\n");
        rc = -ENOMEM;
        goto err_alloc_device;
    }

    kp->key_sense_irq = platform_get_irq(pdev, 0);
    if (kp->key_sense_irq < 0) {
        dev_err(&pdev->dev, "unable to get keypad sense irq\n");
        rc = -ENXIO;
        goto err_get_irq;
    }

    kp->key_stuck_irq = platform_get_irq(pdev, 1);
    if (kp->key_stuck_irq < 0) {
        dev_err(&pdev->dev, "unable to get keypad stuck irq\n");
        rc = -ENXIO;
        goto err_get_irq;
    }

    kp->input->name = pdata->input_name ? : "PMIC8XXX keypad";
    kp->input->phys = pdata->input_phys_device ? : "pmic8xxx_keypad/input0";

    kp->input->dev.parent	= &pdev->dev;

    kp->input->id.bustype	= BUS_I2C;
    kp->input->id.version	= 0x0001;
    kp->input->id.product	= 0x0001;
    kp->input->id.vendor	= 0x0001;

    kp->input->evbit[0]	= BIT_MASK(EV_KEY);

    if (pdata->rep)
        __set_bit(EV_REP, kp->input->evbit);

    kp->input->keycode	= kp->keycodes;
    kp->input->keycodemax	= PM8XXX_MATRIX_MAX_SIZE;
    kp->input->keycodesize	= sizeof(kp->keycodes);
    kp->input->open		= pmic8xxx_kp_open;
    kp->input->close	= pmic8xxx_kp_close;

    matrix_keypad_build_keymap(keymap_data, PM8XXX_ROW_SHIFT,
                               kp->input->keycode, kp->input->keybit);

    input_set_capability(kp->input, EV_KEY, KEY_VOLUMEDOWN);
    input_set_capability(kp->input, EV_KEY, KEY_VOLUMEUP);
    input_set_capability(kp->input, EV_KEY, KEY_HOME);
    input_set_drvdata(kp->input, kp);

    /* initialize keypad state */
    memset(kp->keystate, 0xff, sizeof(kp->keystate));
    memset(kp->stuckstate, 0xff, sizeof(kp->stuckstate));

    rc = pmic8xxx_kpd_init(kp);
    if (rc < 0) {
        dev_err(&pdev->dev, "unable to initialize keypad controller\n");
        goto err_get_irq;
    }

    rc = pmic8xxx_kp_config_gpio(pdata->cols_gpio_start,
                                 pdata->num_cols, kp, &kypd_sns);
    if (rc < 0) {
        dev_err(&pdev->dev, "unable to configure keypad sense lines\n");
        goto err_gpio_config;
    }

    rc = pmic8xxx_kp_config_gpio(pdata->rows_gpio_start,
                                 pdata->num_rows, kp, &kypd_drv);
    if (rc < 0) {
        dev_err(&pdev->dev, "unable to configure keypad drive lines\n");
        goto err_gpio_config;
    }

    rc = request_any_context_irq(kp->key_sense_irq, pmic8xxx_kp_irq,
                                 IRQF_TRIGGER_RISING, "pmic-keypad", kp);
    if (rc < 0) {
        dev_err(&pdev->dev, "failed to request keypad sense irq\n");
        goto err_get_irq;
    }

    rc = request_any_context_irq(kp->key_stuck_irq, pmic8xxx_kp_stuck_irq,
                                 IRQF_TRIGGER_RISING, "pmic-keypad-stuck", kp);
    if (rc < 0) {
        dev_err(&pdev->dev, "failed to request keypad stuck irq\n");
        goto err_req_stuck_irq;
    }

    rc = pmic8xxx_kp_read_u8(kp, &ctrl_val, KEYP_CTRL);
    if (rc < 0) {
        dev_err(&pdev->dev, "failed to read KEYP_CTRL register\n");
        goto err_pmic_reg_read;
    }

    kp->ctrl_reg = ctrl_val;

    rc = input_register_device(kp->input);
    if (rc < 0) {
        dev_err(&pdev->dev, "unable to register keypad input device\n");
        goto err_pmic_reg_read;
    }

    rc = device_create_file(&pdev->dev, &dev_attr_key_pressed);
    if (rc < 0)
        goto err_create_file;

    rc = device_create_file(&pdev->dev, &dev_attr_disable_kp);
    if (rc < 0)
        goto err_create_file;

    device_init_wakeup(&pdev->dev, pdata->wakeup);

    return 0;

err_create_file:
    free_irq(kp->key_stuck_irq, kp);
err_pmic_reg_read:
    free_irq(kp->key_stuck_irq, kp);
err_req_stuck_irq:
    free_irq(kp->key_sense_irq, kp);
err_gpio_config:
err_get_irq:
    input_free_device(kp->input);
err_alloc_device:
    platform_set_drvdata(pdev, NULL);
    kfree(kp);
    return rc;
}

static int __devexit pmic8xxx_kp_remove(struct platform_device *pdev)
{
    struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);

    device_init_wakeup(&pdev->dev, 0);
    free_irq(kp->key_stuck_irq, kp);
    free_irq(kp->key_sense_irq, kp);
    input_unregister_device(kp->input);
    kfree(kp);

    platform_set_drvdata(pdev, NULL);
    return 0;
}

#ifdef CONFIG_PM_SLEEP
static int pmic8xxx_kp_suspend(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
    struct input_dev *input_dev = kp->input;

    if (device_may_wakeup(dev)) {
        enable_irq_wake(kp->key_sense_irq);
    } else {
        mutex_lock(&input_dev->mutex);

        if (input_dev->users)
            pmic8xxx_kp_disable(kp);

        mutex_unlock(&input_dev->mutex);
    }

    return 0;
}

static int pmic8xxx_kp_resume(struct device *dev)
{
    struct platform_device *pdev = to_platform_device(dev);
    struct pmic8xxx_kp *kp = platform_get_drvdata(pdev);
    struct input_dev *input_dev = kp->input;

    if (device_may_wakeup(dev)) {
        disable_irq_wake(kp->key_sense_irq);
    } else {
        mutex_lock(&input_dev->mutex);

        if (input_dev->users)
            pmic8xxx_kp_enable(kp);

        mutex_unlock(&input_dev->mutex);
    }

    return 0;
}
#endif

static SIMPLE_DEV_PM_OPS(pm8xxx_kp_pm_ops,
                         pmic8xxx_kp_suspend, pmic8xxx_kp_resume);

static struct platform_driver pmic8xxx_kp_driver = {
    .probe		= pmic8xxx_kp_probe,
    .remove		= __devexit_p(pmic8xxx_kp_remove),
    .driver		= {
        .name = PM8XXX_KEYPAD_DEV_NAME,
        .owner = THIS_MODULE,
        .pm = &pm8xxx_kp_pm_ops,
    },
};

static int __init pmic8xxx_kp_init(void)
{
    return platform_driver_register(&pmic8xxx_kp_driver);
}
module_init(pmic8xxx_kp_init);

static void __exit pmic8xxx_kp_exit(void)
{
    platform_driver_unregister(&pmic8xxx_kp_driver);
}
module_exit(pmic8xxx_kp_exit);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("PMIC8XXX keypad driver");
MODULE_VERSION("1.0");
MODULE_ALIAS("platform:pmic8xxx_keypad");
MODULE_AUTHOR("Trilok Soni <*****@*****.**>");
예제 #4
0
static int __devinit modemctl_probe(struct platform_device *pdev)
{
	struct modemctl_platform_data *pdata = pdev->dev.platform_data;
	struct device *dev = &pdev->dev;
	struct modemctl *mc;
	int irq;
	int error;

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

	mc = kzalloc(sizeof(struct modemctl), GFP_KERNEL);
	if (!mc) {
		dev_err(dev, "Failed to allocate device\n");
		return -ENOMEM;
	}

	mc->gpio_phone_on = pdata->gpio_phone_on;
	mc->gpio_phone_active = pdata->gpio_phone_active;
	mc->gpio_pda_active = pdata->gpio_pda_active;
	mc->gpio_cp_reset = pdata->gpio_cp_reset;
	mc->gpio_cp_reset_msm = pdata->gpio_cp_reset_msm;
//	mc->gpio_cp_req_reset = pdata->gpio_cp_req_reset;
//	mc->gpio_ipc_slave_wakeup = pdata->gpio_ipc_slave_wakeup;
//	mc->gpio_ipc_host_wakeup = pdata->gpio_ipc_host_wakeup;
//	mc->gpio_suspend_request = pdata->gpio_suspend_request;
//	mc->gpio_active_state = pdata->gpio_active_state;
//	mc->gpio_usim_boot = pdata->gpio_usim_boot;
//	mc->gpio_flm_sel = pdata->gpio_flm_sel;
//	mc->gpio_cp_dump_int = pdata->gpio_cp_dump_int;
	mc->ops = &pdata->ops;
	mc->gpio_boot_sw_sel = pdata->gpio_boot_sw_sel; // p1_prime
	mc->usb_boot = false;

	mc->dev = dev;
	dev_set_drvdata(mc->dev, mc);

	error = sysfs_create_group(&mc->dev->kobj, &modemctl_group);
	if (error) {
		dev_err(dev, "Failed to create sysfs files\n");
		goto fail;
	}
	mc->group = &modemctl_group;

	INIT_DELAYED_WORK(&mc->work, mc_work);
//	INIT_WORK(&mc->cpdump_work, mc_cpdump_worker);
	wake_lock_init(&mc->reset_lock, WAKE_LOCK_SUSPEND, "modemctl");

	mc->ops->modem_cfg_gpio();

	irq = gpio_to_irq(pdata->gpio_phone_active);
	error = request_irq(irq, modemctl_irq_handler,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
			"phone_active", mc);
	if (error) {
		dev_err(dev, "Failed to allocate an interrupt(%d)\n", irq);
		goto fail;
	}
	mc->irq[0] = irq;
	enable_irq_wake(irq);

//	irq = gpio_to_irq(pdata->gpio_ipc_host_wakeup);

//	error = request_threaded_irq(irq, NULL, modemctl_resume_thread,
//			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
//			"IPC_HOST_WAKEUP", mc);

//	if (error) {
//		dev_err(dev, "Failed to allocate an interrupt(%d)\n", irq);
//		goto fail;
//	}
//	mc->irq[1] = irq;
//	enable_irq_wake(irq);

//	irq = gpio_to_irq(pdata->gpio_cp_dump_int);
//	error = request_irq(irq, modemctl_cpdump_irq,
//			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
//			"CP_DUMP_INT", mc);
//	if (error) {
//		dev_err(dev, "Failed to allocate an interrupt(%d)\n", irq);
//		goto fail;
//	}
//	mc->irq[2] = irq;
//	enable_irq_wake(irq);
//	mc->debug_cnt = 0;

	device_init_wakeup(&pdev->dev, pdata->wakeup);
	platform_set_drvdata(pdev, mc);
	global_mc = mc;
	return 0;

fail:
	_free_all(mc);
	return error;
}
static int baseband_xmm_power_driver_probe(struct platform_device *device)
{
	struct baseband_power_platform_data *data
		= (struct baseband_power_platform_data *)
			device->dev.platform_data;
	struct device *dev = &device->dev;
	unsigned long flags;
	int err, i;
	int ap_wake_irq;

	pr_info("%s\n", __func__);
	pr_info("[XMM] enum_delay_ms=%ld\n", enum_delay_ms);

	/* check for platform data */
	if (!data)
		return -ENODEV;

	/* check if supported modem */
	if (data->baseband_type != BASEBAND_XMM) {
		pr_err("unsuppported modem\n");
		return -ENODEV;
	}

	/* save platform data */
	baseband_power_driver_data = data;

	/* create device file */
	/*err = device_create_file(dev, &dev_attr_xmm_onoff);
	if (err < 0) {
		pr_err("%s - device_create_file failed\n", __func__);
		return -ENODEV;
	}*/

	/* init wake lock */
	wake_lock_init(&wakelock, WAKE_LOCK_SUSPEND, "baseband_xmm_power");
	wake_lock_init(&modem_recovery_wakelock, WAKE_LOCK_SUSPEND, "modem_recovery");

	/* init spin lock */
	spin_lock_init(&xmm_lock);
	/* request baseband gpio(s) */
	tegra_baseband_gpios[0].gpio = baseband_power_driver_data
		->modem.xmm.bb_rst;
	tegra_baseband_gpios[1].gpio = baseband_power_driver_data
		->modem.xmm.bb_on;
	tegra_baseband_gpios[2].gpio = baseband_power_driver_data
		->modem.xmm.ipc_bb_wake;
	tegra_baseband_gpios[3].gpio = baseband_power_driver_data
		->modem.xmm.ipc_ap_wake;
	tegra_baseband_gpios[4].gpio = baseband_power_driver_data
		->modem.xmm.ipc_hsic_active;
	tegra_baseband_gpios[5].gpio = baseband_power_driver_data
		->modem.xmm.ipc_hsic_sus_req;
	tegra_baseband_gpios[6].gpio = baseband_power_driver_data
		->modem.xmm.bb_vbat;
	tegra_baseband_gpios[7].gpio = baseband_power_driver_data
		->modem.xmm.ipc_bb_rst_ind;
	tegra_baseband_gpios[8].gpio = baseband_power_driver_data
		->modem.xmm.ipc_bb_force_crash;
	err = gpio_request_array(tegra_baseband_gpios,
		ARRAY_SIZE(tegra_baseband_gpios));
	if (err < 0) {
		pr_err("%s - request gpio(s) failed\n", __func__);
		return -ENODEV;
	}

	/* location is at /sys/devices/platform/baseband_xmm_power */
	for (i = 0; i < (ARRAY_SIZE(xmm_device_attr) - 1); i++) {
		err = device_create_file(dev, &xmm_device_attr[i]);
		if (err) {
			pr_err("create file %d failed, err = %d\n", i, err);
			goto failed_create_file;
		}
	}

	/* get regulator LDO7 for hsic power */
	if (!reg_grouper_hsic) {
		reg_grouper_hsic = regulator_get(NULL, "vddio_hsic");
		if (IS_ERR_OR_NULL(reg_grouper_hsic)) {
			pr_err("grouper 3G HSIC power on LDO7 failed\n");
			reg_grouper_hsic = NULL;
			return PTR_ERR(reg_grouper_hsic);
		}
		regulator_set_voltage(reg_grouper_hsic, 1200000, 1200000);
	}

	/* request baseband irq(s) */
	if (modem_flash && modem_pm) {
		pr_debug("%s: request_irq IPC_AP_WAKE_IRQ\n", __func__);
		ipc_ap_wake_state = IPC_AP_WAKE_UNINIT;
		err = request_threaded_irq(
			gpio_to_irq(data->modem.xmm.ipc_ap_wake),
			NULL,
			baseband_xmm_power_ipc_ap_wake_irq,
			IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
			"IPC_AP_WAKE_IRQ",
			NULL);
		if (err < 0) {
			pr_err("%s - request irq IPC_AP_WAKE_IRQ failed\n",
				__func__);
			return err;
		}
		ap_wake_irq = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
                tegra_pm_irq_set_wake_type(ap_wake_irq, IRQF_TRIGGER_FALLING);
                enable_irq_wake(ap_wake_irq);
		if (err < 0)
			 pr_err("%s: enable_irq_wake error\n", __func__);
		ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
		if (modem_ver >= XMM_MODEM_VER_1130) {
			pr_debug("%s: ver > 1130: AP_WAKE_INIT1\n", __func__);
			/* ver 1130 or later starts in INIT1 state */
			ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
		}
	}

	/* init work queue */
	workqueue = create_singlethread_workqueue
		("baseband_xmm_power_workqueue");
	if (!workqueue) {
		pr_err("cannot create workqueue\n");
		return -1;
	}
	baseband_xmm_power_work = (struct baseband_xmm_power_work_t *)
		kmalloc(sizeof(struct baseband_xmm_power_work_t), GFP_KERNEL);
	if (!baseband_xmm_power_work) {
		pr_err("cannot allocate baseband_xmm_power_work\n");
		return -1;
	}
	INIT_WORK((struct work_struct *) baseband_xmm_power_work,
		baseband_xmm_power_work_func);
	baseband_xmm_power_work->state = BBXMM_WORK_INIT;
	queue_work(workqueue,
		(struct work_struct *) baseband_xmm_power_work);

	/* init work objects */
	INIT_WORK(&init1_work, baseband_xmm_power_init1_work);
	INIT_WORK(&init2_work, baseband_xmm_power_init2_work);
	INIT_WORK(&L2_resume_work, baseband_xmm_power_L2_resume_work);
	INIT_WORK(&autopm_resume_work, baseband_xmm_power_autopm_resume);

	/* init state variables */
	register_hsic_device = true;
	CP_initiated_L2toL0 = false;
	spin_lock_irqsave(&xmm_lock, flags);
	baseband_xmm_powerstate = BBXMM_PS_UNINIT;
	wakeup_pending = false;
	spin_unlock_irqrestore(&xmm_lock, flags);

	usb_register_notify(&usb_xmm_nb);

	pr_debug("%s }\n", __func__);
	return 0;

failed_create_file:
	while (i--)
		device_remove_file(dev, &xmm_device_attr[i]);
	return err;
}
static int pn547_probe(struct i2c_client *client,
        const struct i2c_device_id *id)
{
    int ret;
    struct pn547_dev *pn547_dev = NULL;
    pn547_client = client;

    dprintk(PN547_DRV_NAME ": pn547_probe() start\n");

    pn547_dev = kzalloc(sizeof(*pn547_dev), GFP_KERNEL);
    if (pn547_dev == NULL) {
        dev_err(&client->dev,
                "failed to allocate memory for module data\n");
        ret = -ENOMEM;
        goto err_exit;
    }

    pn547_parse_dt(&client->dev, pn547_dev);

    pn547_dev->client   = client;
    dprintk(PN547_DRV_NAME ":IRQ : %d\nVEN : %d\nFIRM : %d\n",
            pn547_dev->irq_gpio, pn547_dev->ven_gpio, pn547_dev->firm_gpio);

    ret = gpio_request(pn547_dev->irq_gpio, "nfc_int");
    if (ret) {
        dprintk(PN547_DRV_NAME ":pn547_probe() : nfc_int request failed!\n");
        goto err_int;
    }
    ret = gpio_request(pn547_dev->ven_gpio, "nfc_ven");
    if (ret) {
        dprintk(PN547_DRV_NAME ":pn547_probe() : nfc_ven request failed!\n");
        goto err_ven;
    }
    ret = gpio_request(pn547_dev->firm_gpio, "nfc_firm");
    if (ret) {
        dprintk(PN547_DRV_NAME ":pn547_probe() : nfc_firm request failed!\n");
        goto err_firm;
    }

    pn547_gpio_enable(pn547_dev);

    ret = gpio_direction_output(pn547_dev->ven_gpio,1);
    ret = gpio_direction_output(pn547_dev->firm_gpio,0);
    ret = gpio_direction_input(pn547_dev->irq_gpio);

    /* init mutex and queues */
    init_waitqueue_head(&pn547_dev->read_wq);
    mutex_init(&pn547_dev->read_mutex);
    spin_lock_init(&pn547_dev->irq_enabled_lock);

    pn547_dev->pn547_device.minor = MISC_DYNAMIC_MINOR;
    pn547_dev->pn547_device.name = PN547_DRV_NAME;
    pn547_dev->pn547_device.fops = &pn547_dev_fops;

    ret = misc_register(&pn547_dev->pn547_device);
    if (ret) {
        pr_err("%s : misc_register failed\n", __FILE__);
        goto err_misc_register;
    }

    wake_lock_init(&nfc_wake_lock, WAKE_LOCK_SUSPEND, "NFCWAKE");

    /* request irq.  the irq is set whenever the chip has data available
     * for reading.  it is cleared when all data has been read.
     */
    pr_info("%s : requesting IRQ %d\n", __func__, client->irq);
    pn547_dev->irq_enabled = true;
    ret = request_irq(pn547_gpio_to_irq(pn547_dev), pn547_dev_irq_handler,
              IRQF_TRIGGER_RISING|IRQF_NO_SUSPEND, client->name, pn547_dev);
    if (ret) {
        dev_err(&client->dev, "request_irq failed\n");
        goto err_request_irq_failed;
    }
    enable_irq_wake(pn547_get_irq_pin(pn547_dev));
    pn547_disable_irq(pn547_dev);
    i2c_set_clientdata(client, pn547_dev);
    dprintk(PN547_DRV_NAME ": pn547_probe() end\n");
    return 0;

err_request_irq_failed:
    misc_deregister(&pn547_dev->pn547_device);

err_misc_register:
    mutex_destroy(&pn547_dev->read_mutex);
    gpio_free(pn547_dev->firm_gpio);

err_firm:
    gpio_free(pn547_dev->ven_gpio);

err_ven:
    gpio_free(pn547_dev->irq_gpio);

err_int:
    kfree(pn547_dev);

err_exit:
    pr_err(PN547_DRV_NAME ": pn547_dev is null\n");
    pr_err(PN547_DRV_NAME ": pn547_probe() end with error!\n");

    return ret;
}
static int __devinit tps6591x_rtc_probe(struct platform_device *pdev)
{
	struct tps6591x_rtc_platform_data *pdata = pdev->dev.platform_data;
	struct tps6591x_rtc *rtc;
	struct rtc_time tm;
	int err;
	u8 reg;

	rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);

	if (!rtc)
		return -ENOMEM;

	rtc->irq = -1;

	if (!pdata) {
		dev_err(&pdev->dev, "no platform_data specified\n");
		return -EINVAL;
	}

	if (pdata->irq < 0)
		dev_err(&pdev->dev, "\n no IRQ specified, wakeup is disabled\n");

	dev_set_drvdata(&pdev->dev, rtc);
	device_init_wakeup(&pdev->dev, 1);
	rtc->rtc = rtc_device_register(pdev->name, &pdev->dev,
				       &tps6591x_rtc_ops, THIS_MODULE);

	if (IS_ERR(rtc->rtc)) {
		err = PTR_ERR(rtc->rtc);
		goto fail;
	}

	if ((int)pdev && (int)&pdev->dev)
		err = tps6591x_read_regs(&pdev->dev, RTC_STATUS, 1, &reg);
	else {
		dev_err(&pdev->dev, "\n %s Input params incorrect\n", __func__);
		return -EBUSY;
	}
	if (err) {
		dev_err(&pdev->dev, "\n %s unable to read status\n", __func__);
		return -EBUSY;
	}

	reg = RTC_BBCH_SEL | RTC_BBCH_EN;
	tps6591x_write_regs(&pdev->dev, RTC_BBCH_REG, 1, &reg);
	if (err) {
		dev_err(&pdev->dev, "unable to program Charger reg\n");
		return -EBUSY;
	}

	tps6591x_rtc_read_time(&pdev->dev, &tm);
	if ((tm.tm_year < RTC_YEAR_OFFSET || tm.tm_year > (RTC_YEAR_OFFSET + 99))){
		if (pdata->time.tm_year < 2000 || pdata->time.tm_year > 2100)	{
			memset(&pdata->time, 0, sizeof(pdata->time));
			pdata->time.tm_year = RTC_YEAR_OFFSET;
			pdata->time.tm_mday = 1;
		} else
		pdata->time.tm_year -= OS_REF_YEAR;
		tps6591x_rtc_set_time(&pdev->dev, &pdata->time);
	}

	reg = ALARM_INT_STATUS;
	err = tps6591x_write_regs(&pdev->dev, RTC_STATUS, 1, &reg);
	if (err) {
		dev_err(&pdev->dev, "unable to program RTC_STATUS reg\n");
		return -EBUSY;
	}

	reg = ENABLE_ALARM_INT;
	tps6591x_write_regs(&pdev->dev, RTC_INT, 1, &reg);
	if (err) {
		dev_err(&pdev->dev, "unable to program Interrupt Mask reg\n");
		return -EBUSY;
	}

	if (pdata && (pdata->irq >= 0)) {
		rtc->irq = pdata->irq;
		err = request_threaded_irq(pdata->irq, NULL, tps6591x_rtc_irq,
					IRQF_ONESHOT, "rtc_tps6591x",
					&pdev->dev);
		if (err) {
			dev_err(&pdev->dev, "request IRQ:%d fail\n", rtc->irq);
			rtc->irq = -1;
		} else {
			device_init_wakeup(&pdev->dev, 1);
			enable_irq_wake(rtc->irq);
		}
	}
	return 0;

fail:
	if (!IS_ERR_OR_NULL(rtc->rtc))
		rtc_device_unregister(rtc->rtc);
	kfree(rtc);
	return err;
}
예제 #8
0
static int __devinit max14526_probe(struct i2c_client *client,
		const struct i2c_device_id *id)
{
	int ret = 0;
	TYPE_MUIC_MODE muic_mode;
	struct ts5usb_device *dev = NULL;
	struct muic_platform_data *pdata = client->dev.platform_data;

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

	if (!pdata) {
		dev_err(&client->dev, "muic: %s: no platform data\n", __func__);
		return -EINVAL;
	}

	dev = kzalloc(sizeof(struct ts5usb_device), GFP_KERNEL);
	if (!dev) {
		dev_err(&client->dev, "muic: %s: no memory\n", __func__);
		return -ENOMEM;
	}

	dev->client = client;
	dev->gpio_int = pdata->gpio_int;
#if defined(CONFIG_MHL)
	dev->gpio_mhl = pdata->gpio_mhl;
	dev->gpio_ifx_vbus = pdata->gpio_ifx_vbus;
#endif
	dev->irq = client->irq;

	max14526 = client;

	/* Initializes gpio_165 (USIF1_SW). */
	ret = gpio_request(USIF_IN_1_GPIO, "USIF switch control GPIO");
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] GPIO 165 USIF1_SW is already occupied by other driver!\n");
		/*
		 * We know board_cosmo.c:ifx_n721_configure_gpio() performs a gpio_request on this pin first.
		 * Because the prior gpio_request is also for the analog switch control, this is not a confliction.
		 */
		return -ENOSYS;
	}

	ret = gpio_direction_output(USIF_IN_1_GPIO, 0);
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] gpio_16 USIF_IN_1_GPIO direction initialization failed!\n");
		return -ENOSYS;
	}

	/*  Initializes gpio_11 (OMAP_UART_SW) and gpio_12 (IFX_UART_SW) */
	ret = gpio_request(DP3T_IN_1_GPIO, "DP3T switch control 1 GPIO");
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] GPIO 11 DP3T_IN_1_GPIO is already occupied by other driver!\n");
		return -ENOSYS;
	}

	ret = gpio_direction_output(DP3T_IN_1_GPIO, 0);
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] gpio_11 DP3T_IN_1_GPIO direction initialization failed!\n");
		return -ENOSYS;
	}

	ret = gpio_request(DP3T_IN_2_GPIO, "DP3T switch control 2 GPIO");
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] gpio_12 DP3T_IN_2_GPIO is already occupied by other driver!\n");
		return -ENOSYS;
	}

	ret = gpio_direction_output(DP3T_IN_2_GPIO, 0);
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] gpio_12 DP3T_IN_2_GPIO direction initialization failed!\n");
		return -ENOSYS;
	}

	ret = gpio_request(IFX_USB_VBUS_EN_GPIO, "DP3T switch control 2 GPIO");
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] gpio_55 IFX_USB_VBUS_EN_GPIO is already occupied by other driver!\n");
		return -ENOSYS;
	}

	ret = gpio_direction_output(IFX_USB_VBUS_EN_GPIO, 0);
	if (ret < 0) {
		printk(KERN_INFO "[MUIC] gpio_55 IFX_USB_VBUS_EN_GPIO direction initialization failed!\n");
		return -ENOSYS;
	}

	/*
	 * Initializes gpio_wk8 (MUIC_INT_N).
	 * Checks if other driver already occupied it.
	 */
	ret = gpio_request(dev->gpio_int, "MUIC IRQ GPIO");
	if (ret < 0) {
		dev_err(&client->dev, "muic: GPIO %d is already used\n",	dev->gpio_int);
		ret = -ENOSYS;
		goto err_gpio_request;
	}
	/* Initializes GPIO direction before use or IRQ setting */
	gpio_direction_input(dev->gpio_int);

	/* Registers MUIC work queue function */
	INIT_WORK(&dev->muic_wq, max14526_wq_func);

	/*
	 * Set up an IRQ line and enable the involved interrupt handler.
	 * From this point, a MUIC_INT_N can invoke muic_interrupt_handler().
	 * muic_interrupt_handler merely calls schedule_work() with muic_wq_func().
	 * muic_wq_func() actually performs the accessory detection.
	 */
	ret = request_irq(dev->irq, max14526_interrupt_handler,IRQF_TRIGGER_FALLING, "muic_irq", dev);
	if (ret < 0) 
	{
		dev_err(&client->dev, "muic: %s: request_irq failed!\n",__func__);
		goto err_request_irq;
	}

	//disable_irq_wake(gpio_to_irq(MUIC_INT));

	/* Prepares a human accessible method to control MUIC */
	//create_cosmo_muic_proc_file();

	/* Selects one of the possible muic chips */
	//muic_detect_device();

	wake_lock_init(&dev->muic_wake_lock, WAKE_LOCK_SUSPEND,"muic_wake_lock");

	ret = muic_device_register(&muic_dev, NULL);
	if (ret < 0) {
		dev_err(&client->dev, "muic: %s: muic_device_register failed\n",__func__);
		goto err_muic_device_register;
	}

	i2c_set_clientdata(client, dev);

	// hunsoo.lee
	printk("%s, registering ops\n", __func__);
	muic_client_dev_register(dev->client->name, dev, &max14526_ops);

	/* Initializes MUIC - Finally MUIC INT becomes enabled */
	if (BOOT_RECOVERY == muic_retain_mode) 
	{ /* Recovery mode */
		muic_mode = MUIC_CP_UART;
		muic_init_max14526(client, BOOTUP);
		dev_info(&client->dev, "muic: %s: first boot\n", __func__);
	}
	else 
	{
		muic_init_max14526(client, RESET);
		muic_max14526_detect_accessory(client, NOT_UPON_IRQ);
		muic_mode = muic_get_mode();
	}
	muic_set_mode(muic_mode);

	/* Makes the interrupt on MUIC INT wake up OMAP which is in suspend mode */
	ret = enable_irq_wake(dev->irq);
	if (ret < 0) {
		dev_err(&client->dev, "muic: GPIO %d wake up source setting failed!\n", dev->gpio_int);
		disable_irq_wake(dev->irq);
		goto err_irq_wake;
	}

	dev_info(&client->dev, "muic: muic_probe()\n");

	return ret;

err_irq_wake:
	muic_device_unregister(&muic_dev);
err_muic_device_register:
	wake_lock_destroy(&dev->muic_wake_lock);
	free_irq(dev->irq, dev);
err_request_irq:
	gpio_free(dev->gpio_int);
err_gpio_request:
	kfree(dev);

	return ret;
}
예제 #9
0
static int tab3_wm1811_init_paiftx(struct snd_soc_pcm_runtime *rtd)
{
	struct snd_soc_codec *codec = rtd->codec;
	struct wm1811_machine_priv *wm1811
		= snd_soc_card_get_drvdata(codec->card);
	struct snd_soc_dai *aif1_dai = rtd->codec_dai;
	struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec);
	int ret;

	midas_snd_set_mclk(true, false);

	rtd->codec_dai->driver->playback.channels_max =
				rtd->cpu_dai->driver->playback.channels_max;

	ret = snd_soc_add_controls(codec, tab3_controls,
					ARRAY_SIZE(tab3_controls));

#if defined(CONFIG_TAB3_00_BD)
	if(system_rev < 2) {
		ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets_rev0,
				ARRAY_SIZE(tab3_dapm_widgets_rev0));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

		ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes_rev0,
				ARRAY_SIZE(tab3_dapm_routes_rev0));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
	} else {
		ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets,
				ARRAY_SIZE(tab3_dapm_widgets));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

		ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes,
				ARRAY_SIZE(tab3_dapm_routes));
		if (ret != 0)
			dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);
	}
#else
	ret = snd_soc_dapm_new_controls(&codec->dapm, tab3_dapm_widgets,
			ARRAY_SIZE(tab3_dapm_widgets));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM widgets: %d\n", ret);

	ret = snd_soc_dapm_add_routes(&codec->dapm, tab3_dapm_routes,
			ARRAY_SIZE(tab3_dapm_routes));
	if (ret != 0)
		dev_err(codec->dev, "Failed to add DAPM routes: %d\n", ret);

#endif

	ret = snd_soc_dai_set_sysclk(aif1_dai, WM8994_SYSCLK_MCLK2,
				     MIDAS_DEFAULT_MCLK2, SND_SOC_CLOCK_IN);
	if (ret < 0)
		dev_err(codec->dev, "Failed to boot clocking\n");

	/* Force AIF1CLK on as it will be master for jack detection */
	if (wm8994->revision > 1) {
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "AIF1CLK");
		if (ret < 0)
			dev_err(codec->dev, "Failed to enable AIF1CLK: %d\n",
					ret);
	}

	ret = snd_soc_dapm_disable_pin(&codec->dapm, "S5P RP");
	if (ret < 0)
		dev_err(codec->dev, "Failed to disable S5P RP: %d\n", ret);

	snd_soc_dapm_ignore_suspend(&codec->dapm, "RCV");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "SPK");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "HP");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Headset Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Sub Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Main Mic");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3DACDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF1ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF2ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "AIF3ADCDAT");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "FM In");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "LINE");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "HDMI");
	snd_soc_dapm_ignore_suspend(&codec->dapm, "Third Mic");

	wm1811->codec = codec;

	tab3_micd_set_rate(codec);

#ifdef CONFIG_SEC_DEV_JACK
	/* By default use idle_bias_off, will override for WM8994 */
	codec->dapm.idle_bias_off = 0;
#if defined (CONFIG_TAB3_00_BD)
	if(system_rev < 2) {
		ret = snd_soc_dapm_force_enable_pin(&codec->dapm, "MICBIAS2");
		if (ret < 0)
			dev_err(codec->dev, "Failed to enable MICBIAS2: %d\n",
					ret);
	}
#endif
#else /* CONFIG_SEC_DEV_JACK */
	wm1811->jack.status = 0;

	ret = snd_soc_jack_new(codec, "Tab3 Jack",
				SND_JACK_HEADSET | SND_JACK_BTN_0 |
				SND_JACK_BTN_1 | SND_JACK_BTN_2,
				&wm1811->jack);

	if (ret < 0)
		dev_err(codec->dev, "Failed to create jack: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_0, KEY_MEDIA);

	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_MEDIA: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_1,
							KEY_VOLUMEUP);
	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_VOLUMEUP: %d\n", ret);

	ret = snd_jack_set_key(wm1811->jack.jack, SND_JACK_BTN_2,
							KEY_VOLUMEDOWN);

	if (ret < 0)
		dev_err(codec->dev, "Failed to set KEY_VOLUMEDOWN: %d\n", ret);

	if (wm8994->revision > 1) {
		dev_info(codec->dev, "wm1811: Rev %c support mic detection\n",
			'A' + wm8994->revision);
		ret = wm8958_mic_detect(codec, &wm1811->jack, NULL,
				NULL, tab3_mic_id, wm1811);

		if (ret < 0)
			dev_err(codec->dev, "Failed start detection: %d\n",
				ret);
	} else {
		dev_info(codec->dev, "wm1811: Rev %c doesn't support mic detection\n",
			'A' + wm8994->revision);
		codec->dapm.idle_bias_off = 0;
	}
	/* To wakeup for earjack event in suspend mode */
	enable_irq_wake(control->irq);

	wake_lock_init(&wm1811->jackdet_wake_lock,
					WAKE_LOCK_SUSPEND, "Tab3_jackdet");

	/* To support PBA function test */
	jack_class = class_create(THIS_MODULE, "audio");

	if (IS_ERR(jack_class))
		pr_err("Failed to create class\n");

	jack_dev = device_create(jack_class, NULL, 0, codec, "earjack");

	if (device_create_file(jack_dev, &dev_attr_select_jack) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_select_jack.attr.name);

	if (device_create_file(jack_dev, &dev_attr_key_state) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_key_state.attr.name);

	if (device_create_file(jack_dev, &dev_attr_state) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_state.attr.name);

	if (device_create_file(jack_dev, &dev_attr_reselect_jack) < 0)
		pr_err("Failed to create device file (%s)!\n",
			dev_attr_reselect_jack.attr.name);

#endif /* CONFIG_SEC_DEV_JACK */
	return snd_soc_dapm_sync(&codec->dapm);
}
예제 #10
0
/*
int anx7816_get_sbl_cable_type(void)
{
	int cable_type = 0;
	unsigned int *p_cable_type = (unsigned int *)
		(smem_get_entry(SMEM_ID_VENDOR1, &cable_smem_size));

	if (p_cable_type)
		cable_type = *p_cable_type;
	else
		cable_type = 0;

	return cable_type;
}
*/
static int anx7816_i2c_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{

	struct anx7816_data *anx7816;
	struct anx7816_platform_data *pdata;
	int ret = 0;
	//int sbl_cable_type = 0;

	pr_err("%s %s start\n", LOG_TAG, __func__);

#ifdef SP_REGISTER_SET_TEST
	val_SP_TX_LT_CTRL_REG0 = 0x01;
	val_SP_TX_LT_CTRL_REG1 = 0x03;
	val_SP_TX_LT_CTRL_REG2 = 0x57;
	val_SP_TX_LT_CTRL_REG3 = 0x7f;
	val_SP_TX_LT_CTRL_REG4 = 0x71;
	val_SP_TX_LT_CTRL_REG5 = 0x6b;
	val_SP_TX_LT_CTRL_REG6 = 0x7f;
	val_SP_TX_LT_CTRL_REG7 = 0x73;
	val_SP_TX_LT_CTRL_REG8 = 0x7f;
	val_SP_TX_LT_CTRL_REG9 = 0x7f;
	val_SP_TX_LT_CTRL_REG10 = 0x00;
	val_SP_TX_LT_CTRL_REG11 = 0x00;
	val_SP_TX_LT_CTRL_REG12 = 0x02;
	val_SP_TX_LT_CTRL_REG13 = 0x00;
	val_SP_TX_LT_CTRL_REG14 = 0x0c;
	val_SP_TX_LT_CTRL_REG15 = 0x42;
	val_SP_TX_LT_CTRL_REG16 = 0x1e;
	val_SP_TX_LT_CTRL_REG17 = 0x3e;
	val_SP_TX_LT_CTRL_REG18 = 0x72;
	val_SP_TX_LT_CTRL_REG19 = 0x7e;
#endif
	if (!i2c_check_functionality(client->adapter,
		I2C_FUNC_SMBUS_I2C_BLOCK)) {
		pr_err("%s: i2c bus does not support the anx7816\n", __func__);
		ret = -ENODEV;
		goto exit;
	}

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

	if (client->dev.of_node) {
		pdata = devm_kzalloc(&client->dev,
							 sizeof(struct anx7816_platform_data),
							 GFP_KERNEL);
		if (!pdata) {
			pr_err("%s: Failed to allocate memory\n", __func__);
			return -ENOMEM;
		}
		client->dev.platform_data = pdata;
	/* device tree parsing function call */
		ret = anx7816_parse_dt(&client->dev, pdata);
		if (ret != 0) /* if occurs error */
			goto err0;

		anx7816->pdata = pdata;
	} else {
		anx7816->pdata = client->dev.platform_data;
	}

	/* to access global platform data */
	g_pdata = anx7816->pdata;

	anx7816_client = client;

	mutex_init(&anx7816->lock);

	if (!anx7816->pdata) {
		ret = -EINVAL;
		goto err0;
	}

	ret = anx7816_init_gpio(anx7816);
	if (ret) {
		pr_err("%s: failed to initialize gpio\n", __func__);
		goto err0;
	}

	INIT_DELAYED_WORK(&anx7816->work, anx7816_work_func);
/*	INIT_DELAYED_WORK(&anx7816->dwc3_ref_clk_work, dwc3_ref_clk_work_func); */

	anx7816->workqueue = create_singlethread_workqueue("anx7816_work");
	if (anx7816->workqueue == NULL) {
		pr_err("%s: failed to create work queue\n", __func__);
		ret = -ENOMEM;
		goto err1;
	}

	//anx7816->pdata->avdd_power(1);
	//anx7816->pdata->dvdd_power(1);

	ret = anx7816_system_init();
	if (ret) {
		pr_err("%s: failed to initialize anx7816\n", __func__);
		goto err2;
	}

	client->irq = gpio_to_irq(anx7816->pdata->gpio_cbl_det);
	if (client->irq < 0) {
		pr_err("%s : failed to get gpio irq\n", __func__);
		goto err2;
	}

	wake_lock_init(&anx7816->slimport_lock,
				WAKE_LOCK_SUSPEND,
				"slimport_wake_lock");

	//sbl_cable_type = anx7816_get_sbl_cable_type();

/*                                                
                               */ 
//	{

		ret = request_threaded_irq(client->irq, NULL, anx7816_cbl_det_isr,
						IRQF_TRIGGER_RISING
						| IRQF_TRIGGER_FALLING
						| IRQF_ONESHOT,
						"anx7816", anx7816);
		if (ret  < 0) {
			pr_err("%s : failed to request irq\n", __func__);
			goto err2;
		}

		ret = irq_set_irq_wake(client->irq, 1);
		if (ret  < 0) {
			pr_err("%s : Request irq for cable detect", __func__);
			pr_err("interrupt wake set fail\n");
			goto err3;
		}

		ret = enable_irq_wake(client->irq);
		if (ret  < 0) {
			pr_err("%s : Enable irq for cable detect", __func__);
			pr_err("interrupt wake enable fail\n");
			goto err3;
		}
/*	} else {
		pr_err("%s %s : %s, Disable cbl det irq!!\n", LOG_TAG, __func__,
			sbl_cable_type == CBL_910K ? "910K Cable Connected" : "Laf Mode");
	}
*/
	ret = create_sysfs_interfaces(&client->dev);
	if (ret < 0) {
		pr_err("%s : sysfs register failed", __func__);
		goto err3;
	}
#ifdef CONFIG_SLIMPORT_DYNAMIC_HPD
	hdmi_slimport_ops = devm_kzalloc(&client->dev,
				    sizeof(struct msm_hdmi_slimport_ops),
				    GFP_KERNEL);
	if (!hdmi_slimport_ops) {
		pr_err("%s: alloc hdmi slimport ops failed\n", __func__);
		ret = -ENOMEM;
		goto err3;
	}

	if (anx7816->pdata->hdmi_pdev) {
		ret = msm_hdmi_register_slimport(anx7816->pdata->hdmi_pdev,
					   hdmi_slimport_ops, anx7816);
		if (ret) {
			pr_err("%s: register with hdmi failed\n", __func__);
			ret = -EPROBE_DEFER;
			goto err3;
		}
	}
#endif
	pr_info("%s %s end\n", LOG_TAG, __func__);
	goto exit;

err3:
	free_irq(client->irq, anx7816);
err2:
	destroy_workqueue(anx7816->workqueue);
err1:
	anx7816_free_gpio(anx7816);
err0:
	anx7816_client = NULL;
	kfree(anx7816);
exit:
	return ret;
}
예제 #11
0
static ssize_t proximity_enable_store(struct device *dev,
					struct device_attribute *attr,
					const char *buf, size_t size)
{
	struct cm36686_data *cm36686 = dev_get_drvdata(dev);
	bool new_value;

	if (sysfs_streq(buf, "1"))
		new_value = true;
	else if (sysfs_streq(buf, "0"))
		new_value = false;
	else {
		pr_err("[SENSOR] %s: invalid value %d\n", __func__, *buf);
		return -EINVAL;
	}

	mutex_lock(&cm36686->power_lock);
	pr_info("%s, new_value = %d\n", __func__, new_value);
	if (new_value && !(cm36686->power_state & PROXIMITY_ENABLED)) {
		u8 val = 1;
		int i;
#ifdef CM36686_CANCELATION
		int err = 0;
#endif
		cm36686->power_state |= PROXIMITY_ENABLED;
#if defined(CONFIG_SENSORS_CM36686_LEDA_EN_GPIO)
		cm36686_leden_gpio_onoff(cm36686, 1);
#else
	prox_led_onoff(cm36686, 1);
#endif
#ifdef CM36686_CANCELATION
		/* open cancelation data */
		err = proximity_open_cancelation(cm36686);
		if (err < 0 && err != -ENOENT)
			pr_err("[SENSOR] %s: proximity_open_cancelation() failed\n",
				__func__);
#endif
		/* enable settings */
		for (i = 0; i < PS_REG_NUM; i++) {
			cm36686_i2c_write_word(cm36686,
				ps_reg_init_setting[i][REG_ADDR],
				ps_reg_init_setting[i][CMD]);
		}

		val = gpio_get_value(cm36686->pdata->irq);
		/* 0 is close, 1 is far */
		input_report_abs(cm36686->proximity_input_dev,
			ABS_DISTANCE, val);
		input_sync(cm36686->proximity_input_dev);

		enable_irq(cm36686->irq);
		enable_irq_wake(cm36686->irq);
	} else if (!new_value && (cm36686->power_state & PROXIMITY_ENABLED)) {
		cm36686->power_state &= ~PROXIMITY_ENABLED;

		disable_irq_wake(cm36686->irq);
		disable_irq(cm36686->irq);
		/* disable settings */
		cm36686_i2c_write_word(cm36686, REG_PS_CONF1, 0x0001);
#if defined(CONFIG_SENSORS_CM36686_LEDA_EN_GPIO)
		cm36686_leden_gpio_onoff(cm36686, 0);
#else
	prox_led_onoff(cm36686, 0);
#endif
	}
	mutex_unlock(&cm36686->power_lock);
	return size;
}
static int xmm_power_on(struct platform_device *device)
{
	struct baseband_power_platform_data *pdata =
			device->dev.platform_data;
	struct xmm_power_data *data = &xmm_power_drv_data;
	unsigned long flags;
	int ret;

	pr_debug("%s {\n", __func__);

	/* check for platform data */
	if (!pdata) {
		pr_err("%s: !pdata\n", __func__);
		return -EINVAL;
	}
	if (baseband_xmm_get_power_status() != BBXMM_PS_UNINIT)
		return -EINVAL;

	/* reset the state machine */
	baseband_xmm_set_power_status(BBXMM_PS_INIT);
	modem_sleep_flag = false;
	modem_acked_resume = true;

	pr_debug("%s wake_st(%d) modem version %lu\n", __func__,
				ipc_ap_wake_state, modem_ver);

	/* register usb host controller */
	if (!modem_flash) {
		pr_debug("%s - %d\n", __func__, __LINE__);

		spin_lock_irqsave(&xmm_lock, flags);
		ipc_ap_wake_state = IPC_AP_WAKE_INIT2;
		spin_unlock_irqrestore(&xmm_lock, flags);

		/* register usb host controller only once */
		if (register_hsic_device) {
			pr_debug("%s: register usb host controller\n",
				__func__);
			modem_power_on = true;
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register
					(pdata->ehci_device);
			else
				pr_err("%s: hsic_register is missing\n",
					__func__);
			register_hsic_device = false;
			baseband_modem_power_on(pdata);
		} else {
			/* register usb host controller */
			if (pdata->hsic_register)
				data->hsic_device = pdata->hsic_register
					(pdata->ehci_device);
			/* turn on modem */
			pr_debug("%s call baseband_modem_power_on_async\n",
								__func__);
			baseband_modem_power_on_async(pdata);
		}
	} else {
		/* reset flashed modem then it will respond with
		 * ap-wake rising followed by falling gpio
		 */

		pr_debug("%s: reset flash modem\n", __func__);

		modem_power_on = false;
		spin_lock_irqsave(&xmm_lock, flags);
		ipc_ap_wake_state = IPC_AP_WAKE_IRQ_READY;
		spin_unlock_irqrestore(&xmm_lock, flags);
		gpio_set_value(pdata->modem.xmm.ipc_hsic_active, 0);
		forced_abort_hubevent = 0;

		xmm_power_reset_on(pdata);
	}

	ret = enable_irq_wake(gpio_to_irq(pdata->modem.xmm.ipc_ap_wake));
	if (ret < 0)
		pr_err("%s: enable_irq_wake error\n", __func__);
	pr_debug("%s }\n", __func__);

	return 0;
}
static ssize_t proximity_enable_store(struct device *dev,
                                      struct device_attribute *attr,
                                      const char *buf, size_t size)
{
    struct gp2a_data *gp2a = dev_get_drvdata(dev);
    bool new_value;
    u8 value;
#ifdef GP2AP002X_PROXIMITY_OFFSET
    int err;
#endif

    if (sysfs_streq(buf, "1")) {
        new_value = true;
    } else if (sysfs_streq(buf, "0")) {
        new_value = false;
    } else {
        pr_err("%s: invalid value %d\n", __func__, *buf);
        return -EINVAL;
    }

    mutex_lock(&gp2a->power_lock);
    gp2a_dbgmsg("new_value = %d, old state = %d\n",
                new_value,
                (gp2a->power_state & PROXIMITY_ENABLED) ? 1 : 0);
    if (new_value && !(gp2a->power_state & PROXIMITY_ENABLED)) {
        pr_info("%s, %d\n", __func__, __LINE__);

#ifdef GP2AP002X_PROXIMITY_OFFSET
        pr_info("%s, %d GP2AP002X_PROXIMITY_OFFSET\n", __func__, __LINE__);
        err = gp2a_cal_mode_read_file(&gp2a->cal_mode);
        if (err < 0 && err != -ENOENT)
            pr_err("%s: cal_mode file read fail\n", __func__);

        pr_info("%s: mode = %02x\n", __func__, gp2a->cal_mode);
        if (gp2a->cal_mode == 2) {
            nondetect = PROX_NONDETECT_MODE2;
            detect = PROX_DETECT_MODE2;
        } else if (gp2a->cal_mode == 1) {
            nondetect = PROX_NONDETECT_MODE1;
            detect = PROX_DETECT_MODE1;
        } else {
            nondetect = PROX_NONDETECT;
            detect = PROX_DETECT;
        }
#endif
        /* We send 1 for far status, 0 for close status */
        gp2a->val_state = 1;
        input_report_abs(gp2a->proximity_input_dev,
                         ABS_DISTANCE,
                         gp2a->val_state);
        input_sync(gp2a->proximity_input_dev);

        gp2a->power_state |= PROXIMITY_ENABLED;
        msleep(20);

        value = 0x18;
        gp2a_i2c_write(gp2a, REGS_CON, &value);

        value = 0x08;
        gp2a_i2c_write(gp2a, REGS_GAIN, &value);
        value = nondetect;
        gp2a_i2c_write(gp2a, REGS_HYS, &value);
        value = 0x04;
        gp2a_i2c_write(gp2a, REGS_CYCLE, &value);

        enable_irq_wake(gp2a->irq);

        value = 0x03;
        gp2a_i2c_write(gp2a, REGS_OPMOD, &value);
        enable_irq(gp2a->irq);
        value = 0x00;
        gp2a_i2c_write(gp2a, REGS_CON, &value);

    } else if (!new_value && (gp2a->power_state & PROXIMITY_ENABLED)) {
        pr_info("%s, %d\n", __func__, __LINE__);

        disable_irq_wake(gp2a->irq);
        disable_irq(gp2a->irq);
        value = 0x02;
        gp2a_i2c_write(gp2a, REGS_OPMOD, &value);
        gp2a->power_state &= ~PROXIMITY_ENABLED;
    }
    mutex_unlock(&gp2a->power_lock);
    return size;
}
예제 #14
0
static int wsa_irq_init(struct wsa_resource *wsa_res)
{
	int i, ret;

	if (wsa_res == NULL) {
		pr_err("%s: wsa_res is NULL\n", __func__);
		return -EINVAL;
	}
	mutex_init(&wsa_res->irq_lock);
	mutex_init(&wsa_res->nested_irq_lock);

	wsa_res->irq = wsa_irq_get_upstream_irq(wsa_res);
	if (!wsa_res->irq) {
		pr_warn("%s: irq driver is not yet initialized\n", __func__);
		mutex_destroy(&wsa_res->irq_lock);
		mutex_destroy(&wsa_res->nested_irq_lock);
		return -EPROBE_DEFER;
	}
	pr_debug("%s: probed irq %d\n", __func__, wsa_res->irq);

	/* Setup downstream IRQs */
	ret = wsa_irq_setup_downstream_irq(wsa_res);
	if (ret) {
		pr_err("%s: Failed to setup downstream IRQ\n", __func__);
		goto fail_irq_init;
	}

	/* mask all the interrupts */
	for (i = 0; i < wsa_res->num_irqs; i++) {
		wsa_res->irq_masks_cur |= BYTE_BIT_MASK(i);
		wsa_res->irq_masks_cache |= BYTE_BIT_MASK(i);
	}

	ret = request_threaded_irq(wsa_res->irq, NULL, wsa_irq_thread,
				   IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
				   "wsa", wsa_res);
	if (ret != 0) {
		dev_err(wsa_res->dev, "Failed to request IRQ %d: %d\n",
			wsa_res->irq, ret);
	} else {
		ret = enable_irq_wake(wsa_res->irq);
		if (ret) {
			dev_err(wsa_res->dev,
				"Failed to set wake interrupt on IRQ %d: %d\n",
				wsa_res->irq, ret);
			free_irq(wsa_res->irq, wsa_res);
		}
	}

	if (ret)
		goto fail_irq_init;

	return ret;

fail_irq_init:
	dev_err(wsa_res->dev,
			"%s: Failed to init wsa irq\n", __func__);
	wsa_irq_put_upstream_irq(wsa_res);
	mutex_destroy(&wsa_res->irq_lock);
	mutex_destroy(&wsa_res->nested_irq_lock);
	return ret;
}
static int ge_counter_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct ge_counter_platform_data *pdata = dev_get_platdata(dev);
	struct driver_data *data;
	struct counter_data *dest;
	unsigned int irq;
	int i, ret;

	if (!pdata) {
		pdata = ge_counter_get_devtree_pdata(dev);
		if (IS_ERR(pdata))
			return PTR_ERR(pdata);
	}

	data = kzalloc(sizeof(struct driver_data) + sizeof(struct counter_data)
			* pdata->num_counter, GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	data->dir = kobject_create_and_add("counter", &pdev->dev.kobj);
	if (!data->dir) {
		dev_err(&pdev->dev, "Cannot create sysfs counter dir 'counter'\n");
		kfree(data);
		return -EIO;
	}

	data->num_counter = pdata->num_counter;
	for (i = 0; i < pdata->num_counter; i++) {
		struct ge_counter *src = &pdata->counter[i];
		dest = &data->vdata[i];

		if (!src->name) {
			dev_err(&pdev->dev, "Counter name must be set\n");
			ret = -EINVAL;
			goto err;
		}

		if (!src->gpio || gpio_request(src->gpio, src->name)) {
			dev_err(&pdev->dev, "Invalid counter GPIO %d\n", src->gpio);
			ret = -EINVAL;
			goto err;
		}

		gpio_direction_input(src->gpio);
		irq = gpio_to_irq(src->gpio);
		enable_irq_wake(irq);
		ret = request_any_context_irq(irq, counter_event, src->irq_type,
				"ge_counter", dest);
		if (ret < 0) {
			dev_err(&pdev->dev, "Cannot request IRQ %u for GPIO %u", irq, src->gpio);
			ret = -EINVAL;
			goto err_gpio;
		}

		dest->subdir = kobject_create_and_add(src->name, data->dir);
		if (!dest->subdir) {
			dev_err(&pdev->dev, "Cannot create sysfs counter dir '%s'\n",
					src->name);
			ret = -EIO;
			goto err_irq;
		}

		spin_lock_init(&dest->lock);

		dest->gpio = src->gpio;
		dest->interval = msecs_to_jiffies(src->interval);
		dest->counter = 0UL;
		dest->start_jiffies = jiffies;
		dest->start_count = 0UL;
		dest->reset_on_read = src->reset_on_read;
		dest->use_timer = false;
		dest->interval_count_valid = false;

		dest->counter_attr.show = counter_show;
		dest->counter_attr.store = counter_store;
		sysfs_attr_init(&dest->counter_attr.attr);
		dest->counter_attr.attr.name = "counter";
		dest->counter_attr.attr.mode = S_IRUGO | S_IWUSR;

		ret = sysfs_create_file(dest->subdir, &dest->counter_attr.attr);
		if (ret)
			goto err_dir;

		dest->elapsed_attr.show = elapsed_show;
		dest->elapsed_attr.store = elapsed_store;
		sysfs_attr_init(&dest->elapsed_attr.attr);
		dest->elapsed_attr.attr.name = "elapsed";
		dest->elapsed_attr.attr.mode = S_IRUGO | S_IWUSR;

		ret = sysfs_create_file(dest->subdir, &dest->elapsed_attr.attr);
		if (ret)
			goto err_file1;

		dest->state_attr.show = state_show;
		sysfs_attr_init(&dest->state_attr.attr);
		dest->state_attr.attr.name = "state";
		dest->state_attr.attr.mode = S_IRUGO;

		ret = sysfs_create_file(dest->subdir, &dest->state_attr.attr);
		if (ret)
			goto err_file2;

		dest->reset_on_read_attr.show = reset_on_read_show;
		dest->reset_on_read_attr.store = reset_on_read_store;
		sysfs_attr_init(&dest->reset_on_read_attr.attr);
		dest->reset_on_read_attr.attr.name = "reset_on_read";
		dest->reset_on_read_attr.attr.mode = S_IRUGO | S_IWUSR;

		ret = sysfs_create_file(dest->subdir, &dest->reset_on_read_attr.attr);
		if (ret)
			goto err_file3;

		if (src->interval) {
			dest->interval_attr.show = interval_show;
			dest->interval_attr.store = interval_store;
			sysfs_attr_init(&dest->interval_attr.attr);
			dest->interval_attr.attr.name = "interval";
			dest->interval_attr.attr.mode = S_IRUGO | S_IWUSR;

			ret = sysfs_create_file(dest->subdir, &dest->interval_attr.attr);
			if (ret)
				goto err_file4;

			dest->interval_count_attr.show = interval_count_show;
			sysfs_attr_init(&dest->interval_count_attr.attr);
			dest->interval_count_attr.attr.name = "interval_count";
			dest->interval_count_attr.attr.mode = S_IRUGO;

			ret = sysfs_create_file(dest->subdir, &dest->interval_count_attr.attr);
			if (ret)
				goto err_file5;

			dest->use_timer = true;
			init_timer(&dest->timer);
			dest->timer.data = (unsigned long)dest;
			dest->timer.function = timeout;
			dest->jiffies = jiffies;
			dest->timer.expires = jiffies + dest->interval;
			add_timer(&dest->timer);
		}
	}

	platform_set_drvdata(pdev, data);
	return 0;

err_file5:
	sysfs_remove_file(dest->subdir, &dest->interval_attr.attr);
err_file4:
	sysfs_remove_file(dest->subdir, &dest->reset_on_read_attr.attr);
err_file3:
	sysfs_remove_file(dest->subdir, &dest->state_attr.attr);
err_file2:
	sysfs_remove_file(dest->subdir, &dest->elapsed_attr.attr);
err_file1:
	sysfs_remove_file(dest->subdir, &dest->counter_attr.attr);
err_dir:
	kobject_put(dest->subdir);
err_irq:
	free_irq(irq, dest);
err_gpio:
	gpio_free(dest->gpio);
err:
	for (--i; i >= 0; i--)
		delete_counter(&data->vdata[i]);

	kobject_put(data->dir);
	kfree(data);
	return ret;
}
예제 #16
0
static int __devinit kp_probe(struct platform_device *pdev)
{
	struct keypad_pmic_mogami_platform_data *pdata = pdev->dev.platform_data;
	struct kp_data *dt;
	struct pm8058_chip *pm_chip = platform_get_drvdata(pdev);
	int rc, i;

	if (pm_chip == NULL) {
		dev_err(&pdev->dev, "no parent pm8058\n");
		return -EINVAL;
	}
	if (pdata == NULL) {
		dev_err(&pdev->dev, "no pdata\n");
		return -EINVAL;
	}

	dt = kzalloc(sizeof(struct kp_data), GFP_KERNEL);
	if (dt == NULL)
		return -ENOMEM;

	dt->pm_chip = pm_chip;
	dt->num_keys = pdata->keymap_size;
	dt->pm_gpio_config = pdata->pm_gpio_config;
	dt->keys = kzalloc(dt->num_keys * sizeof(struct kp_key), GFP_KERNEL);
	if (dt->keys == NULL) {
		rc = -ENOMEM;
		goto err_key_alloc_failed;
	}

	platform_set_drvdata(pdev, dt);
	dt->dev	= &pdev->dev;

	dt->input = input_allocate_device();
	if (dt->input == NULL) {
		dev_err(&pdev->dev, "unable to allocate input device\n");
		rc = -ENOMEM;
		goto err_input_alloc_failed;
	}

	for (i = 0; i < dt->num_keys; ++i) {
		dt->keys[i].irq  = pdata->keymap[i].irq;
		dt->keys[i].gpio = pdata->keymap[i].gpio;
		dt->keys[i].code = pdata->keymap[i].code;
		dt->keys[i].wake = pdata->keymap[i].wake;
		/* our irq status will be a bitmask of the block which
		 * contains a certain gpio. since a block is only eight bits
		 * we need to find the correct bit in the block which
		 * reflects the requested gpio */
		dt->keys[i].id   = (pdata->keymap[i].gpio - 1) % 8;

		set_bit(dt->keys[i].code, dt->input->keybit);
		rc = kp_pm_gpio_config(dt, pm_chip, dt->keys[i].gpio);
		if (rc)
			goto err_bad_gpio_config;
	}

	dt->input->name = pdata->input_name;
	dt->input->phys = KP_DEVICE;
	dt->input->dev.parent	= &pdev->dev;
	dt->input->open		= kp_device_open;
	dt->input->close	= kp_device_close;
	dt->input->id.bustype	= BUS_HOST;
	dt->input->id.version	= 0x0001;
	dt->input->id.product	= 0x0001;
	dt->input->id.vendor	= 0x0001;
	set_bit(EV_KEY, dt->input->evbit);
	input_set_drvdata(dt->input, dt);

	rc = input_register_device(dt->input);
	if (rc < 0) {
		dev_err(&pdev->dev, "unable to register keypad input device\n");
		input_free_device(dt->input);
		goto err_input_register_failed;
	}

	for (i = 0; i < dt->num_keys; ++i) {
		rc = pm8058_irq_get_rt_status(dt->pm_chip, dt->keys[i].irq);
		if (rc < 0) {
			dev_err(&dt->input->dev, "unable to get irq status\n");
			/* non-fatal */
		} else {
			dt->keys[i].state = !rc;
			input_report_key(dt->input, dt->keys[i].code, !rc);
		}
		rc = request_threaded_irq(dt->keys[i].irq, NULL, kp_irq,
				IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
				IRQF_DISABLED, KP_NAME, &dt->input->dev);
		if (rc < 0) {
			dev_err(&dt->input->dev, "unable to request irq\n");
			goto err_request_irq;
		}
		if (!dt->keys[i].wake)
			disable_irq(dt->keys[i].irq);
		else
			enable_irq_wake(dt->keys[i].irq);
	}

	return 0;

 err_request_irq:
	for (--i; i >= 0; --i)
		free_irq(dt->keys[i].irq, &dt->input->dev);
	input_unregister_device(dt->input);
 err_input_register_failed:
 err_bad_gpio_config:
 err_input_alloc_failed:
	kfree(dt->keys);
 err_key_alloc_failed:
	kfree(dt);
	return rc;
}
예제 #17
0
static int yas_probe(struct i2c_client *i2c, const struct i2c_device_id *id)
{
	struct yas_state *st;
	struct iio_dev *indio_dev;
	int ret, i;
	s8 *bias;
	struct yas_acc_platform_data *pdata;

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

	this_client = i2c;
	indio_dev = iio_device_alloc(sizeof(*st));
	if (!indio_dev) {
		ret = -ENOMEM;
		goto error_ret;
	}
	i2c_set_clientdata(i2c, indio_dev);

	indio_dev->name = id->name;
	indio_dev->dev.parent = &i2c->dev;
	indio_dev->info = &yas_info;
	indio_dev->channels = yas_channels;
	indio_dev->num_channels = ARRAY_SIZE(yas_channels);
	indio_dev->modes = INDIO_DIRECT_MODE;

	st = iio_priv(indio_dev);
	st->client = i2c;
	st->sampling_frequency = 20;
	st->acc.callback.device_open = yas_device_open;
	st->acc.callback.device_close = yas_device_close;
	st->acc.callback.device_read = yas_device_read;
	st->acc.callback.device_write = yas_device_write;
	st->acc.callback.usleep = yas_usleep;
	st->acc.callback.current_time = yas_current_time;
	st->indio_dev = indio_dev;
	INIT_DELAYED_WORK(&st->work, yas_work_func);
	INIT_WORK(&st->resume_work, yas_resume_work_func);
	mutex_init(&st->lock);
#ifdef CONFIG_HAS_EARLYSUSPEND
	st->sus.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1;
	st->sus.suspend = yas_early_suspend;
	st->sus.resume = yas_late_resume;
	register_early_suspend(&st->sus);
#endif
	ret = yas_probe_buffer(indio_dev);
	if (ret)
		goto error_free_dev;
	ret = yas_probe_trigger(indio_dev);
	if (ret)
		goto error_remove_buffer;
	ret = iio_device_register(indio_dev);
	if (ret)
		goto error_remove_trigger;
	ret = yas_acc_driver_init(&st->acc);
	if (ret < 0) {
		ret = -EFAULT;
		goto error_unregister_iio;
	}
	ret = st->acc.init();
	if (ret < 0) {
		ret = -EFAULT;
		goto error_unregister_iio;
	}
	ret = st->acc.set_enable(1);
	if (ret < 0) {
		ret = -EFAULT;
		goto error_driver_term;
	}

	pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
	if (pdata == NULL)
		E("%s: memory allocation for pdata failed.", __func__);
	else
		yas_parse_dt(&i2c->dev, pdata);

	for (i = 0; i < 3; i++) {
		st->accel_data[i] = 0;
		bias = (s8 *)&pdata->gs_kvalue;
		st->calib_bias[i] = -(bias[2-i] *
					YAS_GRAVITY_EARTH / 256);
		I("%s: calib_bias[%d] = %d\n", __func__, i, st->calib_bias[i]);
	}

	mutex_lock(&st->lock);
	if ((pdata->placement < 8) && (pdata->placement >= 0)) {
		ret = st->acc.set_position(pdata->placement);
		I("%s: set position = %d\n", __func__, pdata->placement);
	} else {
		ret = st->acc.set_position(5);
		D("%s: set default position = 5\n", __func__);
	}
	mutex_unlock(&st->lock);

#ifdef CONFIG_CIR_ALWAYS_READY
	
	module.IRQ = pdata->intr;
	I("%s: IRQ = %d\n", __func__, module.IRQ);
	ret = request_irq(module.IRQ, kxtj2_irq_handler, IRQF_TRIGGER_RISING,
			"kxtj2", &module);
	enable_irq_wake(module.IRQ);
	if (ret)
		E("%s: Could not request irq = %d\n", __func__, module.IRQ);

	module.kxtj2_wq = create_singlethread_workqueue("kxtj2_wq");
	if (!module.kxtj2_wq) {
		E("%s: Can't create workqueue\n", __func__);
		ret = -ENOMEM;
		goto error_create_singlethread_workqueue;
	}
#endif

	init_irq_work(&st->iio_irq_work, iio_trigger_work);
	g_st = st;

	ret = create_sysfs_interfaces(st);
	if (ret) {
		E("%s: create_sysfs_interfaces fail, ret = %d\n",
		  __func__, ret);
		goto err_create_fixed_sysfs;
	}

	I("%s: Successfully probe\n", __func__);


	return 0;

err_create_fixed_sysfs:

#ifdef CONFIG_CIR_ALWAYS_READY
	if (module.kxtj2_wq)
		destroy_workqueue(module.kxtj2_wq);
error_create_singlethread_workqueue:
#endif
	kfree(pdata);
error_driver_term:
	st->acc.term();
error_unregister_iio:
	iio_device_unregister(indio_dev);
error_remove_trigger:
	yas_remove_trigger(indio_dev);
error_remove_buffer:
	yas_remove_buffer(indio_dev);
error_free_dev:
#ifdef CONFIG_HAS_EARLYSUSPEND
	unregister_early_suspend(&st->sus);
#endif
	iio_device_free(indio_dev);
error_ret:
	i2c_set_clientdata(i2c, NULL);
	this_client = NULL;
	return ret;
}
예제 #18
0
static int cp_timer_suspend(struct cp_watchdog *watchdog)
{
	return enable_irq_wake(watchdog->irq);
}
예제 #19
0
static int ds1374_suspend(struct i2c_client *client, pm_message_t state)
{
	if (client->irq >= 0 && device_may_wakeup(&client->dev))
		enable_irq_wake(client->irq);
	return 0;
}
예제 #20
0
static int __init hub_proxi_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int ret;
	struct hub_proxi_data *data;
	struct device *dev = &client->dev;

	// 20100827 [email protected] [START_LGE]
	hub_proximity_client = client;
	// 20100827 [email protected] [END_LGE]

	//Event_to_application(client);

	data = kzalloc(sizeof(struct hub_proxi_data), GFP_KERNEL);
	if (!data) {
		return -ENOMEM;
	}

	// 20100810 [email protected] GPIO Initialization [START_LGE]
	omap_mux_init_gpio(PROXI_LDO_EN, OMAP_PIN_OUTPUT);
	omap_mux_init_gpio(PROXI_OUT, OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);

	ret = gpio_request(PROXI_LDO_EN, "proximity enable gpio");
	if(ret < 0) {	
		printk("can't get hub proximity enable GPIO\n");
		kzfree(data);
		return -ENOSYS;
	}

	data->use_int_mode = true; //interrupt mode
	//	gpio_request(proxi_output_1, "proxi int gpio");
	//	gpio_direction_input(proxi_output_1); 
	//	request_irq(client->irq, hub_proxi_sleep_int_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "proxi_driver", data); 
	//	enable_irq_wake(client->irq); //wake up irq

	if (data->use_int_mode) {

		printk(KERN_WARNING"%s() : interrupt mode. START\n", __func__);

		if (gpio_request(PROXI_OUT, "proxi interrupt gpio") < 0) {
			printk("can't get hub proxi irq GPIO\n");
			kzfree(data);
			return -ENOSYS;
		}

		ret = gpio_direction_input(PROXI_OUT); 

		ret = request_irq(gpio_to_irq(PROXI_OUT), hub_proxi_int_handler, IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, "proximity_interrupt", data); 
		if (ret < 0){
			printk(KERN_INFO "[Proximity INT] GPIO 14 IRQ line set up failed!\n");
			free_irq(gpio_to_irq(PROXI_OUT), data);
			return -ENOSYS;
		}	
#if 1
		/* Make the interrupt on wake up OMAP which is in suspend mode */		
		ret = enable_irq_wake(gpio_to_irq(PROXI_OUT));		
		if(ret < 0){
			printk(KERN_INFO "[Proximity INT] GPIO 14 wake up source setting failed!\n");
			disable_irq_wake(gpio_to_irq(PROXI_OUT));
			return -ENOSYS;
		}
#endif				
		printk(KERN_WARNING"%s() : interrupt mode. END\n", __func__);

		//		ret = request_irq(client->irq, hub_proxi_int_handler, IRQF_DISABLED | IRQF_TRIGGER_FALLING, "proxi_driver", data); 
	} 
	else {
		hrtimer_init(&data->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		data->timer.function = hub_proxi_timer_func;
		data->delay = PROXI_DEFAULT_DELAY_NS;
		//hrtimer_start(&data->timer, ktime_set(0, data->delay), HRTIMER_MODE_REL);
	}
	INIT_WORK(&data->work, hub_proxi_det_work);

	/*LGE_CHANGE_S [[email protected]] 2010-01-04, ldoc control*/
#if defined(CONFIG_MACH_LGE_HEAVEN_REV_A)
	reg = regulator_get(dev, "vaux3");
	if (reg == NULL) {
		printk(KERN_ERR": Failed to get PROXI power resources !! \n");
		return -ENODEV;
	}
#elif defined(CONFIG_MACH_LGE_HUB)
	reg = regulator_get(dev, "vaux1");
	if (reg == NULL) {
		printk(KERN_ERR": Failed to get PROXI power resources !! \n");
		return -ENODEV;
	}
#endif
	/*LGE_CHANGE_S [[email protected]] 2010-01-04, ldoc control*/

	//hub_proxi_power_onoff(1);
	//hub_proxi_i2c_init(client);

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

	data->input_dev = input_allocate_device();
	if (data->input_dev == NULL) {
		printk(KERN_ERR "%s: input_allocate: not enough memory\n",
				__FUNCTION__);
		return -ENOMEM;
	}

	set_bit(EV_KEY, data->input_dev->evbit);
	set_bit(KEY_POWER, data->input_dev->keybit);
	set_bit(EV_ABS, data->input_dev->evbit);
	input_set_abs_params(data->input_dev, ABS_DISTANCE, 0, 1, 0, 0);
	data->input_dev->name = "proximity";
// 20101004 [email protected], fix initial operation of proximity sensor [START_LGE]
	data->input_dev->abs[ABS_DISTANCE] = -1;
// 20101004 [email protected], fix initial operation of proximity sensor [END_LGE]
	ret = input_register_device(data->input_dev);
	if (ret) {
		printk(KERN_ERR "%s: Fail to register device\n", __FUNCTION__);
		goto ERROR1;
	}

	if ((ret = sysfs_create_group(&dev->kobj, &hub_proxi_group)))
		goto ERROR3;

/* LGE_CHANGE_S, [email protected], 2011-04-13, Sync with P970 */
#ifdef CONFIG_HAS_EARLYSUSPEND /* 20110304 [email protected] late_resume_lcd [START] */
	data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN - 1;
	data->early_suspend.suspend = hub_proxi_early_suspend;
	data->early_suspend.resume = hub_proxi_late_resume;
	register_early_suspend(&data->early_suspend);
#endif /* 20110304 [email protected] late_resume_lcd [END] */
/* LGE_CHANGE_E, [email protected], 2011-04-13, Sync with P970 */

	return 0;

ERROR3:
	input_unregister_device(data->input_dev);
ERROR1:
	kfree(data);

	return ret;
}
예제 #21
0
static void __init gta02_machine_init(void)
{
	int rc;

	/* set the panic callback to make AUX blink fast */
	panic_blink = gta02_panic_blink;

	switch (S3C_SYSTEM_REV_ATAG) {
	case GTA02v6_SYSTEM_REV:
		/* we need push-pull interrupt from motion sensors */
		lis302_pdata_top.open_drain = 0;
		lis302_pdata_bottom.open_drain = 0;
		break;
	default:
		break;
	}

	spin_lock_init(&motion_irq_lock);

#ifdef CONFIG_CHARGER_PCF50633
	INIT_DELAYED_WORK(&gta02_charger_work, gta02_charger_worker);
#endif

	/* Glamo chip select optimization */
/*	 *((u32 *)(S3C2410_MEMREG(((1 + 1) << 2)))) = 0x1280; */

	/* do not force soft ecc if we are asked to use hardware_ecc */
	if (hardware_ecc_str[0] == '1')
		gta02_nand_info.software_ecc = 0;

	s3c_device_usb.dev.platform_data = &gta02_usb_info;
	s3c_device_nand.dev.platform_data = &gta02_nand_info;
	s3c_device_sdi.dev.platform_data = &gta02_s3c_mmc_cfg;

	/* acc sensor chip selects */
	s3c2410_gpio_setpin(S3C2410_GPD12, 1);
	s3c2410_gpio_cfgpin(S3C2410_GPD12, S3C2410_GPIO_OUTPUT);
	s3c2410_gpio_setpin(S3C2410_GPD13, 1);
	s3c2410_gpio_cfgpin(S3C2410_GPD13, S3C2410_GPIO_OUTPUT);

	s3c24xx_udc_set_platdata(&gta02_udc_cfg);
	s3c_i2c0_set_platdata(NULL);
	set_s3c2410ts_info(&gta02_ts_cfg);
	
	mangle_glamo_res_by_system_rev();

	i2c_register_board_info(0, gta02_i2c_devs, ARRAY_SIZE(gta02_i2c_devs));
	spi_register_board_info(gta02_spi_board_info,
				ARRAY_SIZE(gta02_spi_board_info));

#ifdef CONFIG_CHARGER_PCF50633
	mangle_pmu_pdata_by_system_rev();
#endif

	platform_add_devices(gta02_devices, ARRAY_SIZE(gta02_devices));

	s3c_pm_init();

	/* Make sure the modem can wake us up */
	set_irq_type(GTA02_IRQ_MODEM, IRQ_TYPE_EDGE_RISING);
	rc = request_irq(GTA02_IRQ_MODEM, gta02_modem_irq, IRQF_DISABLED,
			 "modem", NULL);
	if (rc < 0)
		printk(KERN_ERR "GTA02: can't request GSM modem wakeup IRQ\n");
	enable_irq_wake(GTA02_IRQ_MODEM);

	/* Make sure the wifi module can wake us up*/
	set_irq_type(GTA02_IRQ_WLAN_GPIO1, IRQ_TYPE_EDGE_RISING);
	rc = request_irq(GTA02_IRQ_WLAN_GPIO1, ar6000_wow_irq, IRQF_DISABLED,
			"ar6000", NULL);

	if (rc < 0)
		printk(KERN_ERR "GTA02: can't request ar6k wakeup IRQ\n");
	enable_irq_wake(GTA02_IRQ_WLAN_GPIO1);

	pm_power_off = gta02_poweroff;

	/* Register the HDQ and vibrator as children of pwm device */
#ifdef CONFIG_HDQ_GPIO_BITBANG
	gta02_hdq_device.dev.parent = &s3c24xx_pwm_device.dev;
	platform_device_register(&gta02_hdq_device);
#endif
#ifdef CONFIG_LEDS_GTA02_VIBRATOR
	gta02_vibrator_dev.dev.parent = &s3c24xx_pwm_device.dev; 
	platform_device_register(&gta02_vibrator_dev);
#endif
}
static int __devinit SM5414_charger_probe(
						struct i2c_client *client,
						const struct i2c_device_id *id)
{
	struct i2c_adapter *adapter =
		to_i2c_adapter(client->dev.parent);
	struct sec_charger_info *charger;
	int ret = 0;

	dev_info(&client->dev,
		"%s: SM5414 Charger Driver Loading\n", __func__);

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

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

	charger->client = client;
	if (client->dev.of_node) {
		void * pdata = kzalloc(sizeof(sec_battery_platform_data_t), GFP_KERNEL);
		if (!pdata)
			goto err_free1;
		charger->pdata = pdata;
		if (SM5414_charger_parse_dt(charger))
			dev_err(&client->dev,
				"%s : Failed to get charger dt\n", __func__);
	} else
		charger->pdata = client->dev.platform_data;

	i2c_set_clientdata(client, charger);

	charger->siop_level = 100;
	charger->psy_chg.name		= "SM5414";
	charger->psy_chg.type		= POWER_SUPPLY_TYPE_UNKNOWN;
	charger->psy_chg.get_property	= SM5414_chg_get_property;
	charger->psy_chg.set_property	= SM5414_chg_set_property;
	charger->psy_chg.properties	= SM5414_charger_props;
	charger->psy_chg.num_properties	= ARRAY_SIZE(SM5414_charger_props);
	charger->is_slow_charging = false;

	if (charger->pdata->chg_gpio_init) {
		if (!charger->pdata->chg_gpio_init()) {
			dev_err(&client->dev,
					"%s: Failed to Initialize GPIO\n", __func__);
			goto err_free;
		}
	}

	if (!SM5414_hal_chg_init(charger->client)) {
		dev_err(&client->dev,
			"%s: Failed to Initialize Charger\n", __func__);
		goto err_free;
	}

	ret = power_supply_register(&client->dev, &charger->psy_chg);
	if (ret) {
		dev_err(&client->dev,
			"%s: Failed to Register psy_chg\n", __func__);
		goto err_free;
	}

	if (charger->pdata->chg_irq) {
		INIT_DELAYED_WORK_DEFERRABLE(
			&charger->isr_work, SM5414_chg_isr_work);

		ret = request_threaded_irq(charger->pdata->chg_irq,
				NULL, SM5414_chg_irq_thread,
				charger->pdata->chg_irq_attr,
				"charger-irq", charger);
		if (ret) {
			dev_err(&client->dev,
				"%s: Failed to Reqeust IRQ\n", __func__);
			goto err_supply_unreg;
		}

		ret = enable_irq_wake(charger->pdata->chg_irq);
		if (ret < 0)
			dev_err(&client->dev,
				"%s: Failed to Enable Wakeup Source(%d)\n",
				__func__, ret);
	}

	ret = SM5414_chg_create_attrs(charger->psy_chg.dev);
	if (ret) {
		dev_err(&client->dev,
			"%s : Failed to create_attrs\n", __func__);
		goto err_req_irq;
	}

	dev_dbg(&client->dev,
		"%s: SM5414 Charger Driver Loaded\n", __func__);
	return 0;

err_req_irq:
	if (charger->pdata->chg_irq)
		free_irq(charger->pdata->chg_irq, charger);
err_supply_unreg:
	power_supply_unregister(&charger->psy_chg);
err_free:
	kfree(charger->pdata);
err_free1:
	kfree(charger);

	return ret;
}
예제 #23
0
int uart_suspend_port(struct uart_driver *drv, struct uart_port *uport)
{
	struct uart_state *state = drv->state + uport->line;
	struct tty_port *port = &state->port;
	struct device *tty_dev;
	struct uart_match match = {uport, drv};

	mutex_lock(&port->mutex);

	tty_dev = device_find_child(uport->dev, &match, serial_match_port);
	if (device_may_wakeup(tty_dev)) {
		if (!enable_irq_wake(uport->irq))
			uport->irq_wake = 1;
		put_device(tty_dev);
		mutex_unlock(&port->mutex);
		return 0;
	}
	put_device(tty_dev);

	if (console_suspend_enabled || !uart_console(uport))
		uport->suspended = 1;

	if (port->flags & ASYNC_INITIALIZED) {
		const struct uart_ops *ops = uport->ops;
		int tries;

		if (console_suspend_enabled || !uart_console(uport)) {
			set_bit(ASYNCB_SUSPENDED, &port->flags);
			clear_bit(ASYNCB_INITIALIZED, &port->flags);

			spin_lock_irq(&uport->lock);
			ops->stop_tx(uport);
			ops->set_mctrl(uport, 0);
			ops->stop_rx(uport);
			spin_unlock_irq(&uport->lock);
		}

		for (tries = 3; !ops->tx_empty(uport) && tries; tries--)
			msleep(10);
		if (!tries)
			printk(KERN_ERR "%s%s%s%d: Unable to drain "
					"transmitter\n",
			       uport->dev ? dev_name(uport->dev) : "",
			       uport->dev ? ": " : "",
			       drv->dev_name,
			       drv->tty_driver->name_base + uport->line);

		if (console_suspend_enabled || !uart_console(uport))
			ops->shutdown(uport);
	}

	if (console_suspend_enabled && uart_console(uport))
		console_stop(uport->cons);

	if (console_suspend_enabled || !uart_console(uport))
		uart_change_pm(state, 3);

	mutex_unlock(&port->mutex);

	return 0;
}
예제 #24
0
static int rk2918_battery_probe(struct platform_device *pdev)
{
	int ret;
	struct adc_client *client;
	struct rk2918_battery_data *data;
	struct rk2918_battery_platform_data *pdata = pdev->dev.platform_data;
	int irq_flag;
	int i = 0;
	
	data = kzalloc(sizeof(*data), GFP_KERNEL);
	if (data == NULL) {
		ret = -ENOMEM;
		goto err_data_alloc_failed;
	}
	gBatteryData = data;

    //clear io
    data->dc_det_pin     = INVALID_GPIO;
    data->batt_low_pin   = INVALID_GPIO;
    data->charge_set_pin = INVALID_GPIO;
	data->charge_ok_pin  = INVALID_GPIO;
	
	if (pdata && pdata->io_init) {
		ret = pdata->io_init();
		if (ret) 
			goto err_free_gpio1;		
	}
	
	//dc det
	if (pdata->dc_det_pin != INVALID_GPIO)
	{
	#ifndef DC_DET_WITH_USB_INT
    	ret = gpio_request(pdata->dc_det_pin, NULL);
    	if (ret) {
    		printk("failed to request dc_det gpio\n");
    		goto err_free_gpio1;
    	}
	#endif
		if(pdata->dc_det_level)
    		gpio_pull_updown(pdata->dc_det_pin, 0);//important
    	else
			gpio_pull_updown(pdata->dc_det_pin, GPIOPullUp);//important
    	ret = gpio_direction_input(pdata->dc_det_pin);
    	if (ret) {
    		printk("failed to set gpio dc_det input\n");
    		goto err_free_gpio1;
    	}
    	data->dc_det_pin   = pdata->dc_det_pin;
    	data->dc_det_level = pdata->dc_det_level;
    }

	if (pdata->charge_cur_ctl != INVALID_GPIO) {

		ret = gpio_request(pdata->charge_cur_ctl, "DC_CURRENT_CONTROL");
		if (ret < 0) {
    		printk("failed to request charge current control gpio\n");
    		goto err_free_gpio2;
		}

		ret = gpio_direction_output(pdata->charge_cur_ctl, !pdata->charge_cur_ctl_level);
		if (ret < 0) {
			printk("rk29_battery: failed to set charge current control gpio\n");
    		goto err_free_gpio2;
		}
		gpio_pull_updown(pdata->charge_cur_ctl, !pdata->charge_cur_ctl_level);
		gpio_set_value(pdata->charge_cur_ctl, !pdata->charge_cur_ctl_level);
		data->charge_cur_ctl = pdata->charge_cur_ctl;
		data->charge_cur_ctl_level = pdata->charge_cur_ctl_level;
	}
	
	//charge set for usb charge
	if (pdata->charge_set_pin != INVALID_GPIO)
	{
    	ret = gpio_request(pdata->charge_set_pin, NULL);
    	if (ret) {
    		printk("failed to request dc_det gpio\n");
    		goto err_free_gpio2;
    	}
    	data->charge_set_pin = pdata->charge_set_pin;
    	data->charge_set_level = pdata->charge_set_level;
    	gpio_direction_output(pdata->charge_set_pin, 1 - pdata->charge_set_level);
    }
	
	//charge_ok
	if (pdata->charge_ok_pin != INVALID_GPIO)
	{
        ret = gpio_request(pdata->charge_ok_pin, NULL);
    	if (ret) {
    		printk("failed to request charge_ok gpio\n");
    		goto err_free_gpio3;
    	}
	
    	gpio_pull_updown(pdata->charge_ok_pin, GPIOPullUp);//important
    	ret = gpio_direction_input(pdata->charge_ok_pin);
    	if (ret) {
    		printk("failed to set gpio charge_ok input\n");
    		goto err_free_gpio3;
    	}
    	data->charge_ok_pin   = pdata->charge_ok_pin;
    	data->charge_ok_level = pdata->charge_ok_level;
    }
    
	client = adc_register(0, rk2918_battery_callback, NULL);
    if(!client)
		goto err_adc_register_failed;
    
	memset(gBatVoltageSamples, 0, sizeof(gBatVoltageSamples));
	spin_lock_init(&data->lock);
    data->adc_val = adc_sync_read(client);
	data->client = client;
    data->battery.properties = rk2918_battery_props;
	data->battery.num_properties = ARRAY_SIZE(rk2918_battery_props);
	data->battery.get_property = rk2918_battery_get_property;
	data->battery.name = "battery";
	data->battery.type = POWER_SUPPLY_TYPE_BATTERY;
	data->adc_bat_divider = 414;
	data->bat_max = BATT_MAX_VOL_VALUE;
	data->bat_min = BATT_ZERO_VOL_VALUE;
	DBG("bat_min = %d\n",data->bat_min);
	
#ifdef RK29_USB_CHARGE_SUPPORT
	data->usb.properties = rk2918_usb_props;
	data->usb.num_properties = ARRAY_SIZE(rk2918_usb_props);
	data->usb.get_property = rk2918_usb_get_property;
	data->usb.name = "usb";
	data->usb.type = POWER_SUPPLY_TYPE_USB;
#endif

	data->ac.properties = rk2918_ac_props;
	data->ac.num_properties = ARRAY_SIZE(rk2918_ac_props);
	data->ac.get_property = rk2918_ac_get_property;
	data->ac.name = "ac";
	data->ac.type = POWER_SUPPLY_TYPE_MAINS;	
	
	rk2918_low_battery_check();
    
	ret = power_supply_register(&pdev->dev, &data->ac);
	if (ret)
	{
		printk(KERN_INFO "fail to ac power_supply_register\n");
		goto err_ac_failed;
	}
#if 0
	ret = power_supply_register(&pdev->dev, &data->usb);
	if (ret)
	{
		printk(KERN_INFO "fail to usb power_supply_register\n");
		goto err_usb_failed;
	}
#endif
	ret = power_supply_register(&pdev->dev, &data->battery);
	if (ret)
	{
		printk(KERN_INFO "fail to battery power_supply_register\n");
		goto err_battery_failed;
	}
	platform_set_drvdata(pdev, data);
	
	INIT_WORK(&data->timer_work, rk2918_battery_timer_work);
	
//    irq_flag = (pdata->charge_ok_level) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
//	ret = request_irq(gpio_to_irq(pdata->charge_ok_pin), rk2918_battery_interrupt, irq_flag, "rk2918_battery", data);
//	if (ret) {
//		printk("failed to request irq\n");
//		goto err_irq_failed;
//	}
#ifndef DC_DET_WITH_USB_INT
    if (pdata->dc_det_pin != INVALID_GPIO)
    {
        irq_flag = (!gpio_get_value (pdata->dc_det_pin)) ? IRQF_TRIGGER_RISING : IRQF_TRIGGER_FALLING;
    	ret = request_irq(gpio_to_irq(pdata->dc_det_pin), rk2918_dc_wakeup, irq_flag, "rk2918_battery", data);
    	if (ret) {
    		printk("failed to request dc det irq\n");
    		goto err_dcirq_failed;
    	}
    	data->dc_det_irq = gpio_to_irq(pdata->dc_det_pin);
    	//data->wq = create_rt_workqueue("rk2918_battery");
    	data->wq = create_workqueue("rk2918_battery");
    	INIT_DELAYED_WORK(&data->work, rk2918_battery_work);
    	
    	enable_irq_wake(gpio_to_irq(pdata->dc_det_pin));
    }
#endif

	setup_timer(&data->timer, rk2918_batscan_timer, (unsigned long)data);
	//data->timer.expires  = jiffies + 2000;
	//add_timer(&data->timer);
   
    rk29_battery_dbg_class = class_create(THIS_MODULE, "rk29_battery");
	battery_dev = device_create(rk29_battery_dbg_class, NULL, MKDEV(0, 1), NULL, "battery");
	ret = device_create_file(battery_dev, &dev_attr_rk29_battery_dbg);
	if (ret)
	{
		printk("create file sys failed!!! \n");
		//goto err_dcirq_failed;
	}
	for(i = 0; i<10; i++)
	{
		ret = device_create_file(&pdev->dev, &dev_attr_startget);
		if (ret)
		{
			printk("make a mistake in creating devices  attr file, failed times: %d\n\n ", i+1);
			continue;
		}
		break;
	}
	printk(KERN_INFO "rk2918_battery: driver initialized\n");
	
	return 0;
	
err_dcirq_failed:
    free_irq(gpio_to_irq(pdata->dc_det_pin), data);
    
err_irq_failed:
	free_irq(gpio_to_irq(pdata->charge_ok_pin), data);
    
err_battery_failed:
//	power_supply_unregister(&data->usb);
//err_usb_failed:
err_ac_failed:
	power_supply_unregister(&data->ac);
	
err_adc_register_failed:
err_free_gpio3:
	gpio_free(pdata->charge_ok_pin);
err_free_gpio2:
	gpio_free(pdata->charge_cur_ctl);
err_free_gpio1:
    gpio_free(pdata->dc_det_pin);
    
err_data_alloc_failed:
	kfree(data);

    printk("rk2918_battery: error!\n");
    
	return ret;
}
static int baseband_xmm_power_on(struct platform_device *device)
{
	struct baseband_power_platform_data *data
		= (struct baseband_power_platform_data *)
			device->dev.platform_data;
	int ret;

	pr_debug("%s {\n", __func__);

	/* check for platform data */
	if (!data) {
		pr_err("%s: !data\n", __func__);
		return -EINVAL;
	}
	if (baseband_xmm_powerstate != BBXMM_PS_UNINIT)
		return -EINVAL;

	/* reset the state machine */
	baseband_xmm_powerstate = BBXMM_PS_INIT;
	modem_sleep_flag = false;

	if (modem_ver < XMM_MODEM_VER_1130)
		ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
	else
		ipc_ap_wake_state = IPC_AP_WAKE_INIT2;

	pr_debug("%s wake_st(%d) modem version %ld\n", __func__,
					ipc_ap_wake_state, modem_ver);

	/* register usb host controller */
	if (!modem_flash) {
		pr_debug("%s - %d\n", __func__, __LINE__);
		/* register usb host controller only once */
		if (register_hsic_device) {
			pr_debug("%s: register usb host controller\n",
				__func__);
			modem_power_on = true;
			if (data->hsic_register)
				data->modem.xmm.hsic_device =
						data->hsic_register();
			else
				pr_err("%s: hsic_register is missing\n",
					__func__);
			register_hsic_device = false;
		} else {
			/* register usb host controller */
			if (data->hsic_register)
				data->modem.xmm.hsic_device =
							data->hsic_register();
			/* turn on modem */
			pr_debug("%s call baseband_modem_power_on\n", __func__);
			baseband_modem_power_on(data);
		}
	}else {
		/* reset flashed modem then it will respond with
		 * ap-wake rising followed by falling gpio
		 */

		pr_debug("%s: reset flash modem\n", __func__);
		modem_power_on = false;
		ipc_ap_wake_state = IPC_AP_WAKE_INIT1;
		gpio_set_value(data->modem.xmm.ipc_hsic_active, 0);
		waiting_falling_flag = 0;

		baseband_xmm_power_reset_on();
	}
	ret = enable_irq_wake(gpio_to_irq(data->modem.xmm.ipc_ap_wake));
	if (ret < 0)
		pr_err("%s: enable_irq_wake error\n", __func__);

	pr_debug("%s }\n", __func__);

	return 0;
}
static int gpio_keypad_request_irqs(struct gpio_kp *kp)
{
	int i;
	int err;
	unsigned int irq;
	unsigned long request_flags;
	struct gpio_event_matrix_info *mi = kp->keypad_info;

	switch (mi->flags & (GPIOKPF_ACTIVE_HIGH|GPIOKPF_LEVEL_TRIGGERED_IRQ)) {
	default:
		request_flags = IRQF_TRIGGER_FALLING;
		break;
	case GPIOKPF_ACTIVE_HIGH:
		request_flags = IRQF_TRIGGER_RISING;
		break;
	case GPIOKPF_LEVEL_TRIGGERED_IRQ:
		request_flags = IRQF_TRIGGER_LOW;
		break;
	case GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_ACTIVE_HIGH:
		request_flags = IRQF_TRIGGER_HIGH;
		break;
	}

//	pr_info("[KEY TEST] %s, %d, %d\n", __func__, __LINE__,request_flags );
	for (i = 0; i < mi->ninputs; i++) {
		err = irq = gpio_to_irq(mi->input_gpios[i]);
		if (err < 0)
			goto err_gpio_get_irq_num_failed;
		err = request_irq(irq, gpio_keypad_irq_handler, request_flags,
				  "gpio_kp", kp);
		if (err) {
			pr_err("gpiomatrix: request_irq failed for input %d, "
				"irq %d\n", mi->input_gpios[i], irq);
			goto err_request_irq_failed;
		}
#ifdef CONFIG_KEYBOARD_WAKEUP	
		switch (mi->input_gpios[i]) {
		case VOLUMEUP_GPIO:
			Volume_Up_irq = irq;
			break;
		case VOLUMEDOWN_GPIO:
			Volume_Down_irq = irq;
			break;
		default:
			break;
		}
#endif
		err = enable_irq_wake(irq);
		if (err) {
			pr_err("gpiomatrix: set_irq_wake failed for input %d, "
				"irq %d\n", mi->input_gpios[i], irq);
		}
		disable_irq(irq);
		if (kp->disabled_irq) {
			kp->disabled_irq = 0;
			enable_irq(irq);
		}
	}
	return 0;

	for (i = mi->noutputs - 1; i >= 0; i--) {
		free_irq(gpio_to_irq(mi->input_gpios[i]), kp);
err_request_irq_failed:
err_gpio_get_irq_num_failed:
		;
	}
	return err;
}
예제 #27
0
파일: bcmsdh.c 프로젝트: Lyude/linux
int brcmf_sdiod_intr_register(struct brcmf_sdio_dev *sdiodev)
{
	struct brcmfmac_sdio_pd *pdata;
	int ret = 0;
	u8 data;
	u32 addr, gpiocontrol;

	pdata = &sdiodev->settings->bus.sdio;
	if (pdata->oob_irq_supported) {
		brcmf_dbg(SDIO, "Enter, register OOB IRQ %d\n",
			  pdata->oob_irq_nr);
		spin_lock_init(&sdiodev->irq_en_lock);
		sdiodev->irq_en = true;

		ret = request_irq(pdata->oob_irq_nr, brcmf_sdiod_oob_irqhandler,
				  pdata->oob_irq_flags, "brcmf_oob_intr",
				  &sdiodev->func1->dev);
		if (ret != 0) {
			brcmf_err("request_irq failed %d\n", ret);
			return ret;
		}
		sdiodev->oob_irq_requested = true;

		ret = enable_irq_wake(pdata->oob_irq_nr);
		if (ret != 0) {
			brcmf_err("enable_irq_wake failed %d\n", ret);
			return ret;
		}
		sdiodev->irq_wake = true;

		sdio_claim_host(sdiodev->func1);

		if (sdiodev->bus_if->chip == BRCM_CC_43362_CHIP_ID) {
			/* assign GPIO to SDIO core */
			addr = CORE_CC_REG(SI_ENUM_BASE, gpiocontrol);
			gpiocontrol = brcmf_sdiod_readl(sdiodev, addr, &ret);
			gpiocontrol |= 0x2;
			brcmf_sdiod_writel(sdiodev, addr, gpiocontrol, &ret);

			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_SELECT,
					   0xf, &ret);
			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_OUT, 0, &ret);
			brcmf_sdiod_writeb(sdiodev, SBSDIO_GPIO_EN, 0x2, &ret);
		}

		/* must configure SDIO_CCCR_IENx to enable irq */
		data = brcmf_sdiod_func0_rb(sdiodev, SDIO_CCCR_IENx, &ret);
		data |= SDIO_CCCR_IEN_FUNC1 | SDIO_CCCR_IEN_FUNC2 |
			SDIO_CCCR_IEN_FUNC0;
		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_IENx, data, &ret);

		/* redirect, configure and enable io for interrupt signal */
		data = SDIO_CCCR_BRCM_SEPINT_MASK | SDIO_CCCR_BRCM_SEPINT_OE;
		if (pdata->oob_irq_flags & IRQF_TRIGGER_HIGH)
			data |= SDIO_CCCR_BRCM_SEPINT_ACT_HI;
		brcmf_sdiod_func0_wb(sdiodev, SDIO_CCCR_BRCM_SEPINT,
				     data, &ret);
		sdio_release_host(sdiodev->func1);
	} else {
		brcmf_dbg(SDIO, "Entering\n");
		sdio_claim_host(sdiodev->func1);
		sdio_claim_irq(sdiodev->func1, brcmf_sdiod_ib_irqhandler);
		sdio_claim_irq(sdiodev->func2, brcmf_sdiod_dummy_irqhandler);
		sdio_release_host(sdiodev->func1);
		sdiodev->sd_irq_requested = true;
	}

	return 0;
}
int gpio_event_matrix_func(struct gpio_event_input_devs *input_devs,
	struct gpio_event_info *info, void **data, int func)
{
	int i;
	int err;
	int key_count;
#ifdef CONFIG_KEYBOARD_WAKEUP	
	int wakeup_keys_status;
	int irq;
	static int irq_status = 1;
#endif
	struct gpio_kp *kp;
	struct gpio_event_matrix_info *mi;

//	pr_info("[KEY TEST] %s, %d \n", __func__, __LINE__);
	mi = container_of(info, struct gpio_event_matrix_info, info);
	if (func == GPIO_EVENT_FUNC_SUSPEND || func == GPIO_EVENT_FUNC_RESUME) {
		/* TODO: disable scanning */
#ifdef CONFIG_KEYBOARD_WAKEUP	
		wakeup_keys_status = gpio_event_get_wakeup_keys_status() & 0x01;

		if (irq_status != wakeup_keys_status)
			irq_status = wakeup_keys_status;
		else
			return 0;


		for (i = 0; i < mi->ninputs; i++) {
			irq = gpio_to_irq(mi->input_gpios[i]);

			if (irq_status == 1)
				err = enable_irq_wake(irq);
			else
				err = disable_irq_wake(irq);
		}
		/* HOME Key is wakeup source */
		for (i = 0; i < mi->nwakeups; i++) {
			irq = gpio_to_irq(mi->wakeup_gpios[i]);
			err = enable_irq_wake(irq);
		}
#endif
		return 0;
	}

	if (func == GPIO_EVENT_FUNC_INIT) {
		if (mi->keymap == NULL ||
		   mi->input_gpios == NULL ||
		   mi->output_gpios == NULL) {
			err = -ENODEV;
			pr_err("gpiomatrix: Incomplete pdata\n");
			goto err_invalid_platform_data;
		}
		key_count = mi->ninputs * mi->noutputs;

		pgpio_key = *data = kp = kzalloc(sizeof(*kp) + sizeof(kp->keys_pressed[0]) *
				     BITS_TO_LONGS(key_count), GFP_KERNEL);
		if (kp == NULL) {
			err = -ENOMEM;
			pr_err("gpiomatrix: Failed to allocate private data\n");
			goto err_kp_alloc_failed;
		}
		kp->input_devs = input_devs;
		kp->keypad_info = mi;
		for (i = 0; i < key_count; i++) {
			unsigned short keyentry = mi->keymap[i];
			unsigned short keycode = keyentry & MATRIX_KEY_MASK;
			unsigned short dev = keyentry >> MATRIX_CODE_BITS;
			if (dev >= input_devs->count) {
				pr_err("gpiomatrix: bad device index %d >= "
					"%d for key code %d\n",
					dev, input_devs->count, keycode);
				err = -EINVAL;
				goto err_bad_keymap;
			}
			if (keycode && keycode <= KEY_MAX)
				input_set_capability(input_devs->dev[dev],
							EV_KEY, keycode);
		}

		for (i = 0; i < mi->noutputs; i++) {
			err = gpio_request(mi->output_gpios[i], "gpio_kp_out");
			if (err) {
				pr_err("gpiomatrix: gpio_request failed for "
					"output %d\n", mi->output_gpios[i]);
				goto err_request_output_gpio_failed;
			}
			if (gpio_cansleep(mi->output_gpios[i])) {
				pr_err("gpiomatrix: unsupported output gpio %d,"
					" can sleep\n", mi->output_gpios[i]);
				err = -EINVAL;
				goto err_output_gpio_configure_failed;
			}
			if (mi->flags & GPIOKPF_DRIVE_INACTIVE)
				err = gpio_direction_output(mi->output_gpios[i],
					!(mi->flags & GPIOKPF_ACTIVE_HIGH));
			else
				err = gpio_direction_input(mi->output_gpios[i]);
			if (err) {
				pr_err("gpiomatrix: gpio_configure failed for "
					"output %d\n", mi->output_gpios[i]);
				goto err_output_gpio_configure_failed;
			}
		}
		for (i = 0; i < mi->ninputs; i++) {
			err = gpio_request(mi->input_gpios[i], "gpio_kp_in");
			if (err) {
				pr_err("gpiomatrix: gpio_request failed for "
					"input %d\n", mi->input_gpios[i]);
				goto err_request_input_gpio_failed;
			}
			err = gpio_direction_input(mi->input_gpios[i]);
			if (err) {
				pr_err("gpiomatrix: gpio_direction_input failed"
					" for input %d\n", mi->input_gpios[i]);
				goto err_gpio_direction_input_failed;
			}
		}
		kp->current_output = mi->noutputs;
		kp->key_state_changed = 1;

		hrtimer_init(&kp->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
		kp->timer.function = gpio_keypad_timer_func;
		wake_lock_init(&kp->wake_lock, WAKE_LOCK_SUSPEND, "gpio_kp");
		err = gpio_keypad_request_irqs(kp);
		kp->use_irq = err == 0;

#ifdef CONFIG_KEYBOARD_WAKEUP	
		kpd_dev = device_create(sec_class, NULL, 0, NULL, "sec_key");
		if (!kpd_dev)
			printk(KERN_WARNING "Failed to create device(sec_key)!\n");
		if (device_create_file(kpd_dev, &dev_attr_sec_key_pressed) < 0)
			printk(KERN_WARNING "Failed to create file(%s)!\n"
				, dev_attr_sec_key_pressed.attr.name);
#endif
		pr_info("GPIO Matrix Keypad Driver: Start keypad matrix for "
			"%s%s in %s mode\n", input_devs->dev[0]->name,
			(input_devs->count > 1) ? "..." : "",
			kp->use_irq ? "interrupt" : "polling");

		if (kp->use_irq)
			wake_lock(&kp->wake_lock);
		hrtimer_start(&kp->timer, ktime_set(0, 0), HRTIMER_MODE_REL);

		return 0;
	}

	err = 0;
	kp = *data;

	if (kp->use_irq)
		for (i = mi->noutputs - 1; i >= 0; i--)
			free_irq(gpio_to_irq(mi->input_gpios[i]), kp);

	hrtimer_cancel(&kp->timer);
	wake_lock_destroy(&kp->wake_lock);
	for (i = mi->noutputs - 1; i >= 0; i--) {
err_gpio_direction_input_failed:
		gpio_free(mi->input_gpios[i]);
err_request_input_gpio_failed:
		;
	}
	for (i = mi->noutputs - 1; i >= 0; i--) {
err_output_gpio_configure_failed:
		gpio_free(mi->output_gpios[i]);
err_request_output_gpio_failed:
		;
	}
err_bad_keymap:
	kfree(kp);
err_kp_alloc_failed:
err_invalid_platform_data:
	return err;
}
예제 #29
0
static int gpio_keys_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
#ifndef CONFIG_MACH_Q1_REV02
	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
#endif
	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
	int i;

	if (device_may_wakeup(&pdev->dev)) {
		for (i = 0; i < pdata->nbuttons; i++) {
			struct gpio_keys_button *button = &pdata->buttons[i];
#ifdef CONFIG_MACH_Q1_REV02
			if (button->wakeup) {
#else
			struct gpio_button_data *bdata = &ddata->data[i];
			if (button->wakeup && !bdata->disabled) {
#endif
				int irq = gpio_to_irq(button->gpio);
				enable_irq_wake(irq);
			}
		}
	}

	return 0;
}

static int gpio_keys_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct gpio_keys_drvdata *ddata = platform_get_drvdata(pdev);
	struct gpio_keys_platform_data *pdata = pdev->dev.platform_data;
	int i;

	for (i = 0; i < pdata->nbuttons; i++) {
		struct gpio_keys_button *button = &pdata->buttons[i];
#ifdef CONFIG_MACH_Q1_REV02
		if (button->wakeup && device_may_wakeup(&pdev->dev)) {
#else
		struct gpio_button_data *bdata = &ddata->data[i];
		if (button->wakeup && !bdata->disabled
		    && device_may_wakeup(&pdev->dev)) {
#endif
			int irq = gpio_to_irq(button->gpio);
			disable_irq_wake(irq);
		}

		gpio_keys_report_event(&ddata->data[i]);
	}
	input_sync(ddata->input);

	return 0;
}

static const struct dev_pm_ops gpio_keys_pm_ops = {
	.suspend	= gpio_keys_suspend,
	.resume		= gpio_keys_resume,
};
#endif

static struct platform_driver gpio_keys_device_driver = {
	.probe		= gpio_keys_probe,
	.remove		= __devexit_p(gpio_keys_remove),
	.driver		= {
		.name	= "sec_key",
		.owner	= THIS_MODULE,
#ifdef CONFIG_PM
		.pm	= &gpio_keys_pm_ops,
#endif
	}
};

static int __init gpio_keys_init(void)
{
	return platform_driver_register(&gpio_keys_device_driver);
}

static void __exit gpio_keys_exit(void)
{
	platform_driver_unregister(&gpio_keys_device_driver);
}

module_init(gpio_keys_init);
module_exit(gpio_keys_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Phil Blundell <*****@*****.**>");
MODULE_DESCRIPTION("Keyboard driver for CPU GPIOs");
MODULE_ALIAS("platform:gpio-keys");
static int cdma_manager_probe(struct platform_device *dev)
{
/*	if (gpio_is_valid(GPIO_CDMA_PWR_ON_OUT)) {
		if (gpio_request(GPIO_CDMA_PWR_ON_OUT, "GPH2")) 
			printk(KERN_ERR "Failed to request GPIO_CDMA_PWR_ON_OUT!\n");
		gpio_direction_output(GPIO_CDMA_PWR_ON_OUT, GPIO_LEVEL_LOW);
	}
	s3c_gpio_setpull(GPIO_CDMA_PWR_ON_OUT, S3C_GPIO_PULL_DOWN);

	if (gpio_is_valid(GPIO_CDMA_RESET_OUT)) {
		if (gpio_request(GPIO_CDMA_RESET_OUT, "GPH2")) 
			printk(KERN_ERR "Failed to request GPIO_CDMA_RESET_OUT!\n");
		gpio_direction_output(GPIO_CDMA_RESET_OUT, GPIO_LEVEL_LOW);
	}
	s3c_gpio_setpull(GPIO_CDMA_RESET_OUT, S3C_GPIO_PULL_NONE);

	if (gpio_is_valid(GPIO_CDMA_READY_SIGNAL_IN)) {
		if (gpio_request(GPIO_CDMA_READY_SIGNAL_IN, "GPH2")) 
			printk(KERN_ERR "Failed to request GPIO_CDMA_READY_SIGNAL_IN!\n");
		
		gpio_direction_input(GPIO_CDMA_READY_SIGNAL_IN);
	}
	s3c_gpio_setpull(GPIO_CDMA_READY_SIGNAL_IN, S3C_GPIO_PULL_DOWN);

	if (gpio_is_valid(GPIO_CDMA_SLEEP_CTL_OUT)) {
		if (gpio_request(GPIO_CDMA_SLEEP_CTL_OUT, "GPH2")) 
			printk(KERN_ERR "Failed to request GPIO_CDMA_SLEEP_CTL_OUT!\n");
		
		gpio_direction_output(GPIO_CDMA_SLEEP_CTL_OUT,1);
	}
	s3c_gpio_setpull(GPIO_CDMA_SLEEP_CTL_OUT, S3C_GPIO_PULL_UP);*/
	int ret = 0;
	int irq;
	ril_wakeup = 1;
	
	ret = device_create_file(&(dev->dev), &dev_attr_wakeup);
	if (ret < 0) {
		printk("failed to add sysfs entries\n");
		return -1;
	}
	
//[yoon 20110504]changed cdma power squency : iriver_init_gpio() -> cdma_manager_probe()
#if 1
	mx100_cdma_power(0); 
#endif

	
    s3c_gpio_cfgpin(GPIO_CDMA_HOST_WAKE, S3C_GPIO_SFN(0xF));
   	s3c_gpio_setpull(GPIO_CDMA_HOST_WAKE, S3C_GPIO_PULL_NONE);

	cdma_uart_port_config(3);

    irq = IRQ_CDMA_HOST_WAKE;
    wake_lock_init(&cdma_wake_lock, WAKE_LOCK_SUSPEND, "cdma_host_wake");
    ret = request_irq(irq, cdma_host_wake_irq_handler,IRQF_TRIGGER_RISING,
                        "cdma_host_wake_irq_handler", NULL);

    if (ret < 0) {
                pr_err("[CDMA] Request_irq failed\n");
                return ret;
    }
    disable_irq(irq);
    ret = enable_irq_wake(irq);
    if (ret < 0)
        pr_err("[CDMA] set wakeup src failed\n");
    enable_irq(irq);

	return 0;
}