Example #1
0
int hdmi_panel_hpd_handler(int hpd)
{
	__cancel_delayed_work(&hpd_work.dwork);
	atomic_set(&hpd_work.state, hpd ? HPD_STATE_START : HPD_STATE_OFF);
	queue_delayed_work(my_workq, &hpd_work.dwork, msecs_to_jiffies(hpd ? 40 : 30));
	return 0;
}
/**
@brief	interrupt handler for a wakeup interrupt

1) Reads the interrupt value\n
2) Performs interrupt handling\n

@param irq	the IRQ number
@param data	the pointer to a data
*/
static irqreturn_t ap_wakeup_handler(int irq, void *data)
{
	struct mem_link_device *mld = (struct mem_link_device *)data;
	struct link_device *ld = &mld->link_dev;
	int ap_wakeup = gpio_get_value(mld->gpio_ap_wakeup);
	int ap_status = gpio_get_value(mld->gpio_ap_status);

	s5p_change_irq_type(irq, ap_wakeup);

	if (!cp_online(ld->mc))
		goto exit;

	if (work_pending(&mld->cp_sleep_dwork.work))
		__cancel_delayed_work(&mld->cp_sleep_dwork);

	print_pm_status(mld);

	if (ap_wakeup) {
		if (!wake_lock_active(&mld->ap_wlock))
			wake_lock(&mld->ap_wlock);

		if (!c2c_suspended() && !ap_status)
			gpio_set_value(mld->gpio_ap_status, 1);
	} else {
		if (wake_lock_active(&mld->ap_wlock))
			wake_unlock(&mld->ap_wlock);

		queue_delayed_work(system_nrt_wq, &mld->cp_sleep_dwork,
				msecs_to_jiffies(CP_WAKEUP_HOLD_TIME));
	}

exit:
	return IRQ_HANDLED;
}
static void handle_power_key_state(unsigned int code, int value)
{
	int ret = 0;
	if (code == KEY_POWER && value == 1) {
		KEY_LOGI("[PWR][STATE]try to schedule power key pressed due\n");
		ret = schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE);
		if (!ret) {
			KEY_LOGI("[PWR][STATE]Schedule power key pressed due failed, seems already have one, try to cancel...\n");
			ret = __cancel_delayed_work(&power_key_state_disable_work);
			if (!ret) {
				setPowerKeyState(1);
				if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
					KEY_LOGI("[PWR][STATE] start count for power key pressed due\n");
					setPowerKeyState(1);
				} else
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
			} else {
				KEY_LOGI("[PWR][STATE]Cancel scheduled power key due success, now re-schedule.\n");
				if (schedule_delayed_work(&power_key_state_disable_work, PWRKEY_PRESS_DUE)) {
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due SCCUESS.\n");
					KEY_LOGI("[PWR][STATE] start count for power key pressed due\n");
					setPowerKeyState(1);
				} else
					KEY_LOGI("[PWR][STATE]Re-schedule power key pressed due FAILED, reason unknown, give up.\n");
			}
		} else {
			KEY_LOGI("[PWR][STATE] start count for power key pressed due\n");
			setPowerKeyState(1);
		}
	}
}
static void disable_reset_func(struct work_struct *work)
{
	struct delayed_work *dwork = container_of(work, struct delayed_work,
									work);
	struct gpio_input_state *ds = container_of(dwork,
			struct gpio_input_state, disable_reset_work);
	const struct gpio_event_direct_entry *key_entry = ds->info->keymap;
	unsigned long irqflags;
	unsigned gpio_flags = ds->info->flags;
	unsigned npolarity;
	uint8_t idx_pwr = 0;
	int i = 0;
	int pressed;

	spin_lock_irqsave(&ds->irq_lock, irqflags);
	ds->disable_reset_flag = 0;
	__cancel_delayed_work(&ds->clear_hw_reset_work);

	for (i = 0; i < ds->info->keymap_size; i++, key_entry++)
		if (key_entry->code == KEY_POWER)
			idx_pwr = i;
	key_entry = ds->info->keymap;
	npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
	pressed = gpio_get_value((key_entry + idx_pwr)->gpio) ^ npolarity;
	handle_transition_according_to_power_key(pressed);

	wake_unlock(&disable_reset_wake_lock);
	spin_unlock_irqrestore(&ds->irq_lock, irqflags);

	KEY_LOGI("%s, %d\n", __func__, ds->disable_reset_flag);
}
static void handle_only_power_key(unsigned int code, int value)
{
	struct gpio_input_state *ds = gb_ddata;

	if (code == KEY_POWER && ds->disable_reset_flag != 0) {
		if (value) {
			queue_delayed_work(ds->disable_reset_wq,
					&ds->clear_hw_reset_work,
					msecs_to_jiffies(0));
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
			clear_kpdpwr_s2_rst_flag = 1;
			KEY_LOGD("%s: Enable kpdpwr s2 reset clear up [%d]\n",
						__func__, clear_kpdpwr_s2_rst_flag);
			hrtimer_start(&clr_kpd_reset_timer,
				ktime_set(0, KPDPWR_CLR_RESET_TIMER), HRTIMER_MODE_REL);
#endif 
		} else {
			__cancel_delayed_work(&ds->clear_hw_reset_work);
#ifdef CONFIG_KPDPWR_S2_DVDD_RESET
			clear_kpdpwr_s2_rst_flag = 0;
			KEY_LOGD("%s: Disable kpdpwr s2 reset clear up [%d]\n",
						__func__, clear_kpdpwr_s2_rst_flag);
			if (hrtimer_is_queued(&clr_kpd_reset_timer))
				hrtimer_cancel(&clr_kpd_reset_timer);
			if (hrtimer_is_queued(&enable_kpd_s2_timer))
				hrtimer_cancel(&enable_kpd_s2_timer);
#endif 
		}
	}
}
#ifdef CONFIG_PM

static int apds9130_suspend(struct i2c_client *client, pm_message_t mesg)
{
#if 1
#else
	struct apds9130_data *data = i2c_get_clientdata(client);

	if(data->sw_mode == PROX_STAT_SHUTDOWN)
		return 0;

	apds9130_set_enable(client, 0);
	apds9130_set_command(client, 2);

	__cancel_delayed_work(&data->dwork);
	flush_delayed_work(&data->dwork);
	flush_workqueue(apds9130_workqueue);

	data->sw_mode = PROX_STAT_SHUTDOWN;
	disable_irq(client->irq);
/*	err = pdata->power(0);
	if(err < 0) {
		printk(KERN_INFO "%s, Proximity Power Off Fail in susped\n",__func__);
		return err;
	}
*/
	irq_set_irq_wake(client->irq, 0);
	if(NULL != apds9130_workqueue){
		destroy_workqueue(apds9130_workqueue);
		printk(KERN_INFO "%s, Destroy workqueue\n",__func__);
		apds9130_workqueue = NULL;
	}
#endif
Example #7
0
void mlx4_ib_invalidate_all_guid_record(struct mlx4_ib_dev *dev, int port)
{
	int i;
	unsigned long flags, flags1;

	pr_debug("port %d\n", port);

	spin_lock_irqsave(&dev->sriov.going_down_lock, flags);
	spin_lock_irqsave(&dev->sriov.alias_guid.ag_work_lock, flags1);
	for (i = 0; i < NUM_ALIAS_GUID_REC_IN_PORT; i++)
		invalidate_guid_record(dev, port, i);

	if (mlx4_is_master(dev->dev) && !dev->sriov.is_going_down) {
		/*
		make sure no work waits in the queue, if the work is already
		queued(not on the timer) the cancel will fail. That is not a problem
		because we just want the work started.
		*/
		__cancel_delayed_work(&dev->sriov.alias_guid.
				      ports_guid[port - 1].alias_guid_work);
		queue_delayed_work(dev->sriov.alias_guid.ports_guid[port - 1].wq,
				   &dev->sriov.alias_guid.ports_guid[port - 1].alias_guid_work,
				   0);
	}
	spin_unlock_irqrestore(&dev->sriov.alias_guid.ag_work_lock, flags1);
	spin_unlock_irqrestore(&dev->sriov.going_down_lock, flags);
}
static void linkwatch_schedule_work(int urgent)
{
	unsigned long delay = linkwatch_nextevent - jiffies;

	if (test_bit(LW_URGENT, &linkwatch_flags))
		return;

	
	if (urgent) {
		if (test_and_set_bit(LW_URGENT, &linkwatch_flags))
			return;
		delay = 0;
	}

	
	if (delay > HZ)
		delay = 0;

	if (schedule_delayed_work(&linkwatch_work, delay) == !delay)
		return;

	
	if (!test_bit(LW_URGENT, &linkwatch_flags))
		return;

	
	if (!__cancel_delayed_work(&linkwatch_work))
		return;

	
	schedule_delayed_work(&linkwatch_work, 0);
}
Example #9
0
static void apds990x_store_als_mean_times( struct apds990x_data *data, uint32_t mean_times )
{
    unsigned long flags;

    APDS_DEBUG_LOG("[IN]%s\n",__func__);
    if( mean_times == 0 )
    {
        APDS_DEBUG_LOG("%s: bad param\n", __func__);
        return;
    }
    else if( mean_times > APDS990X_LUXVALUE_TABLE_MAX )
    {
        data->als_mean_times = APDS990X_LUXVALUE_TABLE_MAX;
    }
    else
    {
        data->als_mean_times = mean_times;
    }
    data->als_poll_delay = 1000 / data->als_mean_times;
    data->als_polling_cnt_reset |= ALS_POLLING_CNT_RESET_STORE_TIME;
    
    spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
    
    __cancel_delayed_work(&data->als_dwork);
    schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
    
    spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);    
    APDS_DEBUG_LOG("[OUT]%s\n",__func__);
}
Example #10
0
static ssize_t apds990x_store_als_poll_delay(struct device *dev,
                    struct device_attribute *attr, const char *buf, size_t count)
{
    struct i2c_client *client = to_i2c_client(dev);
    struct apds990x_data *data = i2c_get_clientdata(client);
    unsigned long val = simple_strtoul(buf, NULL, 10);
    unsigned long flags;
    
    if( val < (1000 / APDS990X_LUXVALUE_TABLE_MAX) * 1000 )
        val = (1000 / APDS990X_LUXVALUE_TABLE_MAX) * 1000;
    
    data->als_poll_delay = val/1000;
    
    data->als_mean_times = 1000 / data->als_poll_delay;
    data->als_polling_cnt_reset |= ALS_POLLING_CNT_RESET_STORE_POLL;

    spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
        
    __cancel_delayed_work(&data->als_dwork);
    schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
            
    spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);    
    
    return count;
}
static void apds9130_reschedule_work(struct apds9130_data *data,
					  unsigned long delay)
{
	/*
	 * If work is already scheduled then subsequent schedules will not
	 * change the scheduled time that's why we have to cancel it first.
	 */
	__cancel_delayed_work(&data->dwork);
	queue_delayed_work(apds9130_workqueue, &data->dwork, delay);

}
Example #12
0
bool mod_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork,
		      unsigned long delay)
{
#ifdef COMPAT_VMWARE
	__cancel_delayed_work(dwork);
#else
	cancel_delayed_work(dwork);
#endif
	queue_delayed_work(wq, dwork, delay);
	return false;
}
Example #13
0
static void apds990x_reschedule_work(struct apds990x_data *data,
                      unsigned long delay)
{
    unsigned long flags;

    spin_lock_irqsave(&data->update_lock.wait_lock, flags);

    __cancel_delayed_work(&data->dwork);
    schedule_delayed_work(&data->dwork, delay);

    spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);
}
Example #14
0
static int apds990x_suspend(struct i2c_client *client, pm_message_t mesg)
{
	struct apds990x_data *data = i2c_get_clientdata(client);
	unsigned long flags;

	spin_lock_irqsave(&data->update_lock.wait_lock, flags);
	__cancel_delayed_work(&data->als_dwork);
	spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);

	return 0;

//	return apds990x_set_enable(client, 0);
}
static int manta_bat_usb_event(struct notifier_block *nb,
			       unsigned long event, void *unused)
{
	int ret;

	if (event == USB_EVENT_ENUMERATED) {
		ret = __cancel_delayed_work(&redetect_work);
		if (ret)
			wake_unlock(&manta_bat_redetect_wl);
	}

	return NOTIFY_OK;
}
int dwc3_intel_byt_after_stop_peripheral(struct dwc_otg2 *otg)
{
	struct intel_dwc_otg_pdata *data;

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;
	if (!data)
		return -EINVAL;

	otg_dbg(otg, "cancel discon work\n");
	__cancel_delayed_work(&data->suspend_discon_work);

	return 0;
}
Example #17
0
static irqreturn_t qt2160_irq(int irq, void *_qt2160)
{
	struct qt2160_data *qt2160 = _qt2160;
	unsigned long flags;

	spin_lock_irqsave(&qt2160->lock, flags);

	__cancel_delayed_work(&qt2160->dwork);
	schedule_delayed_work(&qt2160->dwork, 0);

	spin_unlock_irqrestore(&qt2160->lock, flags);

	return IRQ_HANDLED;
}
static int hs_1wire_open(void)
{
    int ret;
    ret = __cancel_delayed_work(&onewire_closefile_work);
    HS_LOG("[1-wire]hs_1wire_read_key");
    if (!ret) {
        HS_LOG("Cancel fileclose_work failed, ret = %d", ret);
        fp = openFile(hi->pdata.onewire_tty_dev,O_RDWR|O_NONBLOCK,0660);
    }
    wake_lock_timeout(&onewire_open_wake_lock, msecs_to_jiffies(3000));
    queue_delayed_work(onewire_wq, &onewire_closefile_work, msecs_to_jiffies(2000));
    if (!fp)
        return -1;
    return 0;
}
Example #19
0
static void adbs_a330_i2c_reschedule_work(struct adbs_a330_data *data,
					  unsigned long delay)
{
	unsigned long flags;

	spin_lock_irqsave(&data->lock, flags);

	/*
	 * If work is already scheduled then subsequent schedules will not
	 * change the scheduled time that's why we have to cancel it first.
	 */
	__cancel_delayed_work(&data->dwork);
	schedule_delayed_work(&data->dwork, delay);

	spin_unlock_irqrestore(&data->lock, flags);
}
Example #20
0
static int apds990x_resume(struct i2c_client *client)
{
	struct apds990x_data *data = i2c_get_clientdata(client);
	unsigned long flags;

	if(data->enable_als_sensor || data->enable_als_sensor)
	{
		spin_lock_irqsave(&data->update_lock.wait_lock, flags);
		__cancel_delayed_work(&data->als_dwork);
		schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
		spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);
	}

	return 0;

//	return apds990x_set_enable(client, 0);
}
static ssize_t disable_reset_store(struct device *dev,
				struct device_attribute *attr,
				const char *buf, size_t count)
{
	unsigned int value;
	int i = 0;
	int pressed;
	struct gpio_input_state *ds = gb_ddata;
	const struct gpio_event_direct_entry *key_entry = ds->info->keymap;
	struct gpio_key_state *key_state = ds->key_state;
	unsigned gpio_flags = ds->info->flags;
	unsigned npolarity;
	unsigned long irqflags;
	uint8_t idx_pwr = 0;

	if (kstrtouint(buf, 10, &value) < 0) {
		KEY_LOGI("%s: input out of range\n",__func__);
		return -EINVAL;
	}

	spin_lock_irqsave(&ds->irq_lock, irqflags);
	wake_lock(&disable_reset_wake_lock);
	ds->disable_reset_flag = value;
	queue_delayed_work(ds->disable_reset_wq, &ds->disable_reset_work,
			msecs_to_jiffies(ds->disable_reset_flag * 1000));

	for (i = 0; i < ds->info->keymap_size; i++, key_entry++, key_state++)
		if (key_entry->code == KEY_POWER)
			idx_pwr = i;
	key_entry = ds->info->keymap;
	npolarity = !(gpio_flags & GPIOEDF_ACTIVE_HIGH);
#ifdef CONFIG_POWER_KEY_LED
	handle_power_key_led(KEY_POWER, 0);
#endif

	if (__cancel_delayed_work(&power_key_check_reset_work))
		KEY_LOGI("[PWR] cancel power key check reset work successfully\n");

	pressed = gpio_get_value((key_entry + idx_pwr)->gpio) ^ npolarity;
	handle_transition_according_to_power_key(pressed);

	spin_unlock_irqrestore(&ds->irq_lock, irqflags);

	KEY_LOGI("%s, %d\n", __func__, ds->disable_reset_flag);
	return count;
}
Example #22
0
static void hdcp_start_frame_cb(void)
{
	HDCP_DBG("hdcp_start_frame_cb() %ums\n", jiffies_to_msecs(jiffies));

	if (!hdcp.hdcp_keys_loaded) {
		HDCP_DBG("%s: hdcp_keys not loaded = %d\n",
		    __func__, hdcp.hdcp_keys_loaded);
		return;
	}

	/* Cancel any previous work submitted */
	__cancel_delayed_work(&hdcp.hdcp_work->dwork);
	atomic_set(&hdcp.hdcp_work->state, HDCP_STATE_STEP1);
	/* HDCP enable after 7 Vsync delay */
	queue_delayed_work(hdcp.workqueue, &hdcp.hdcp_work->dwork,
				msecs_to_jiffies(300));

}
Example #23
0
static void hdcp_irq_cb(int status)
{
	struct hdmi_ip_data *ip_data;
	u32 intr = 0;

	ip_data = get_hdmi_ip_data();

	if (ip_data->ops->hdcp_int_handler)
		intr = ip_data->ops->hdcp_int_handler(ip_data);

	if (intr == KSVACCESSINT) {
		__cancel_delayed_work(&hdcp.hdcp_work->dwork);
		atomic_set(&hdcp.hdcp_work->state, HDCP_STATE_STEP2);
		queue_delayed_work(hdcp.workqueue, &hdcp.hdcp_work->dwork, 0);
	}

	return;
}
Example #24
0
static ssize_t apds990x_store_als_poll_delay(struct device *dev,
					struct device_attribute *attr, const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct apds990x_data *data = i2c_get_clientdata(client);
	unsigned long val = simple_strtoul(buf, NULL, 10);
//	int ret;
//	int poll_delay=0;
// 	unsigned long flags;
	
	if (val<5000)
		val = 5000;	// minimum 5ms
	
	data->als_poll_delay = val/1000;	// convert us => ms
#if 0	
	poll_delay = 256 - (val/2720);	// the minimum is 2.72ms = 2720 us, maximum is 696.32ms
	if (poll_delay >= 256)
		data->als_atime = 255;
	else if (poll_delay < 0)
		data->als_atime = 0;
	else
		data->als_atime = poll_delay;
	
	ret = apds990x_set_atime(client, data->als_atime);
	
	if (ret < 0)
		return ret;

	/* we need this polling timer routine for sunlight canellation */
	spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
		
	/*
	 * If work is already scheduled then subsequent schedules will not
	 * change the scheduled time that's why we have to cancel it first.
	 */
	__cancel_delayed_work(&data->als_dwork);
	schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));	// 100ms
			
	spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);	
#endif

	return count;
}
static int apds9130_set_ps_poll_delay(struct i2c_client *client, unsigned int val)
{
	struct apds9130_data *data = i2c_get_clientdata(client);
	int ret;
	int wtime=0;
 	
	printk("[ProximitySensor] %s(%d)\n", __func__, val);

	if ((val != APDS9130_PS_POLL_SLOW) && (val != APDS9130_PS_POLL_MEDIUM) && (val != APDS9130_PS_POLL_FAST)) {
		printk("[ProximitySensor_E] %s : invalid value(%d)\n", __func__, val);
		return -1;
	}
	
	if (val == APDS9130_PS_POLL_FAST) {
		data->ps_poll_delay = 50;	// 50ms
		wtime = 0xEE;	// ~50ms
	}
	else if (val == APDS9130_PS_POLL_MEDIUM) {
		data->ps_poll_delay = 100;	// 100ms
		wtime = 0xDC;	// ~100ms
	}
	else {	// APDS9130_PS_POLL_SLOW
		data->ps_poll_delay = 1000;	// 1000ms
		wtime = 0x00;	// 696ms
	}

	ret = apds9130_set_wtime(client, wtime);
	if (ret < 0) 
		return ret;

	/*
	 * If work is already scheduled then subsequent schedules will not
	 * change the scheduled time that's why we have to cancel it first.
	 */
	__cancel_delayed_work(&data->ps_dwork);
	flush_delayed_work(&data->ps_dwork);
	queue_delayed_work(apds9130_workqueue, &data->ps_dwork, msecs_to_jiffies(data->ps_poll_delay));

	return 0;
}
static void linkwatch_schedule_work(int urgent)
{
	unsigned long delay = linkwatch_nextevent - jiffies;

	if (test_bit(LW_URGENT, &linkwatch_flags))
		return;

	/* Minimise down-time: drop delay for up event. */
	if (urgent) {
		if (test_and_set_bit(LW_URGENT, &linkwatch_flags))
			return;
		delay = 0;
	}

	/* If we wrap around we'll delay it by at most HZ. */
	if (delay > HZ)
		delay = 0;

	/*
	 * This is true if we've scheduled it immeditately or if we don't
	 * need an immediate execution and it's already pending.
	 */
	if (schedule_delayed_work(&linkwatch_work, delay) == !delay)
		return;

	/* Don't bother if there is nothing urgent. */
	if (!test_bit(LW_URGENT, &linkwatch_flags))
		return;

	/* It's already running which is good enough. */
	if (!__cancel_delayed_work(&linkwatch_work))
		return;

	/* Otherwise we reschedule it again for immediate execution. */
	schedule_delayed_work(&linkwatch_work, 0);
}
static int apds9130_enable_ps_sensor(struct i2c_client *client, int val)
{
	struct apds9130_data *data = i2c_get_clientdata(client);

	printk("[ProximitySensor] %s(%d)\n", __func__, val);

	if ((val != APDS9130_DISABLE_PS) && (val != APDS9130_ENABLE_PS_WITH_INT) && (val != APDS9130_ENABLE_PS_NO_INT)) {
		printk("[ProximitySensor_E] %s : invalid value(%d)\n", __func__, val);
		return -1;
	}

	/* APDS9130_DISABLE_PS (0) = Disable PS */
	/* APDS9130_ENABLE_PS_WITH_INT (1) = Enable PS with interrupt enabled */
	/* APDS9130_ENABLE_PS_NO_INT (2) = Enable PS without interrupt enabled */

	if(val == APDS9130_ENABLE_PS_WITH_INT || val == APDS9130_ENABLE_PS_NO_INT) {
		//turn on p sensor
		data->enable_ps_sensor = val;

		apds9130_set_enable(client,0); /* Power Off */

		apds9130_set_pilt(client, 1023);		// to force first Near-to-Far interrupt
		apds9130_set_piht(client, 0);

		/*                                               
                                       
                                                                                         
                                         
   */
		apds9130_set_pers(client, APDS9130_PPERS_0);

		if (val == APDS9130_ENABLE_PS_WITH_INT) {
			apds9130_set_enable(client, 0x2D);	 /* enable PS interrupt */

			/*
			 * If work is already scheduled then subsequent schedules will not
			 * change the scheduled time that's why we have to cancel it first.
			 */
			__cancel_delayed_work(&data->ps_dwork);
			flush_delayed_work(&data->ps_dwork);
		}
		else {
			apds9130_set_enable(client, 0x0D);	 /* no PS interrupt */

			/*
			 * If work is already scheduled then subsequent schedules will not
			 * change the scheduled time that's why we have to cancel it first.
			 */
			__cancel_delayed_work(&data->ps_dwork);
			flush_delayed_work(&data->ps_dwork);
			schedule_delayed_work(&data->ps_dwork, msecs_to_jiffies(data->ps_poll_delay));
        }
	}
	else {
		apds9130_set_enable(client, 0);
		data->enable_ps_sensor = 0;

		/*
		 * If work is already scheduled then subsequent schedules will not
		 * change the scheduled time that's why we have to cancel it first.
		 */
		__cancel_delayed_work(&data->ps_dwork);
		flush_delayed_work(&data->ps_dwork);
	}

	return 0;
}
Example #28
0
static ssize_t apds990x_store_enable_ps_sensor(struct device *dev,
				struct device_attribute *attr, const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct apds990x_data *data = i2c_get_clientdata(client);
	unsigned long val = simple_strtoul(buf, NULL, 10);
 	unsigned long flags;
	
	printk("%s: enable ps senosr ( %ld)\n", __func__, val);
	
	if ((val != 0) && (val != 1)) {
		printk("%s:store unvalid value=%ld\n", __func__, val);
		return count;
	}
	
	if(val == 1) {
		//turn on p sensor
		if (data->enable_ps_sensor==0) {

			data->enable_ps_sensor= 1;
		
			apds990x_set_enable(client,0); /* Power Off */
			apds990x_set_atime(client, 0xf6); /* 27.2ms */
			apds990x_set_ptime(client, 0xff); /* 2.72ms */
		
			apds990x_set_ppcount(client, 8); /* 8-pulse */
			apds990x_set_control(client, data->control); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
		
			apds990x_set_pilt(client, 0);		// init threshold for proximity
			apds990x_set_piht(client, APDS990x_PS_DETECTION_THRESHOLD);

			data->ps_threshold = APDS990x_PS_DETECTION_THRESHOLD;
			data->ps_hysteresis_threshold = APDS990x_PS_HSYTERESIS_THRESHOLD;
		
			apds990x_set_ailt( client, 0);
			apds990x_set_aiht( client, 0xffff);
		
			apds990x_set_pers(client, 0x33); /* 3 persistence */
		
			if (data->enable_als_sensor==0) {

				/* we need this polling timer routine for sunlight canellation */
				spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
			
				/*
				 * If work is already scheduled then subsequent schedules will not
				 * change the scheduled time that's why we have to cancel it first.
				 */
				__cancel_delayed_work(&data->als_dwork);
				schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));	// 100ms
			
				spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);	
			}

			apds990x_set_enable(client, 0x27);	 /* only enable PS interrupt */
		}
	} 
	else {
		//turn off p sensor - kk 25 Apr 2011 we can't turn off the entire sensor, the light sensor may be needed by HAL
		data->enable_ps_sensor = 0;
		if (data->enable_als_sensor) {
			
			// reconfigute light sensor setting			
			apds990x_set_enable(client,0); /* Power Off */
			
			apds990x_set_atime(client, data->als_atime);  /* previous als poll delay */
			
			apds990x_set_ailt( client, 0);
			apds990x_set_aiht( client, 0xffff);
			
			apds990x_set_control(client, data->control); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
			apds990x_set_pers(client, 0x33); /* 3 persistence */
			
			apds990x_set_enable(client, 0x3);	 /* only enable light sensor */
			
			spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
			
			/*
			 * If work is already scheduled then subsequent schedules will not
			 * change the scheduled time that's why we have to cancel it first.
			 */
			__cancel_delayed_work(&data->als_dwork);
			schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));	// 100ms
			
			spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);	
			
		}
		else {
			apds990x_set_enable(client, 0);

			spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
			
			/*
			 * If work is already scheduled then subsequent schedules will not
			 * change the scheduled time that's why we have to cancel it first.
			 */
			__cancel_delayed_work(&data->als_dwork);
		
			spin_unlock_irqrestore(&data->update_lock.wait_lock, flags); 
		}
	}
	
	
	return count;
}
Example #29
0
static ssize_t apds990x_store_enable_als_sensor(struct device *dev,
				struct device_attribute *attr, const char *buf, size_t count)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct apds990x_data *data = i2c_get_clientdata(client);
	unsigned long val = simple_strtoul(buf, NULL, 10);
 	unsigned long flags;
	
	printk("%s: enable als sensor ( %ld)\n", __func__, val);
	
	if ((val != 0) && (val != 1))
	{
		printk("%s: enable als sensor=%ld\n", __func__, val);
		return count;
	}
	
	if(val == 1) {
		//turn on light  sensor
		if (data->enable_als_sensor==0) {

			data->enable_als_sensor = 1;
		
			apds990x_set_enable(client,0); /* Power Off */
		
			apds990x_set_atime(client, data->als_atime);  /* 100.64ms */
		
			apds990x_set_ailt( client, 0);
			apds990x_set_aiht( client, 0xffff);
		
			apds990x_set_control(client, data->control); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
			apds990x_set_pers(client, 0x33); /* 3 persistence */
		
			if (data->enable_ps_sensor) {
				apds990x_set_ptime(client, 0xff); /* 2.72ms */
			
				apds990x_set_ppcount(client, 8); /* 8-pulse */
				apds990x_set_enable(client, 0x27);	 /* if prox sensor was activated previously */
			}
			else {
				apds990x_set_enable(client, 0x3);	 /* only enable light sensor */
			}
		
			spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
		
			/*
			 * If work is already scheduled then subsequent schedules will not
			 * change the scheduled time that's why we have to cancel it first.
			 */
			__cancel_delayed_work(&data->als_dwork);
			schedule_delayed_work(&data->als_dwork, msecs_to_jiffies(data->als_poll_delay));
		
			spin_unlock_irqrestore(&data->update_lock.wait_lock, flags);
		}
	}
	else {
		//turn off light sensor
		// what if the p sensor is active?
		data->enable_als_sensor = 0;
		if (data->enable_ps_sensor) {
			apds990x_set_enable(client,0); /* Power Off */
			apds990x_set_atime(client, 0xf6);  /* 27.2ms */
			apds990x_set_ptime(client, 0xff); /* 2.72ms */
			apds990x_set_ppcount(client, 8); /* 8-pulse */
			apds990x_set_control(client, data->control); /* 100mA, IR-diode, 1X PGAIN, 1X AGAIN */
			
			//apds990x_set_piht(client, 0);
			//apds990x_set_piht(client, APDS990x_PS_DETECTION_THRESHOLD);
			
			apds990x_set_ailt( client, 0);
			apds990x_set_aiht( client, 0xffff);
			
			apds990x_set_pers(client, 0x33); /* 3 persistence */
			apds990x_set_enable(client, 0x27);	 /* only enable prox sensor with interrupt */			
		}
		else {
			apds990x_set_enable(client, 0);
		}
		
		
		spin_lock_irqsave(&data->update_lock.wait_lock, flags); 
		
		/*
		 * If work is already scheduled then subsequent schedules will not
		 * change the scheduled time that's why we have to cancel it first.
		 */
		__cancel_delayed_work(&data->als_dwork);
		
		spin_unlock_irqrestore(&data->update_lock.wait_lock, flags); 
	}
	
	return count;
}
static int dwc3_intel_byt_set_power(struct usb_phy *_otg,
		unsigned ma)
{
	unsigned long flags;
	struct dwc_otg2 *otg = dwc3_get_otg();
	struct power_supply_cable_props cap;
	struct intel_dwc_otg_pdata *data;

	data = (struct intel_dwc_otg_pdata *)otg->otg_data;
	if (!data)
		return -EINVAL;

	if (ma == OTG_USB2_100MA ||
		ma == OTG_USB3_150MA ||
		ma == OTG_USB2_500MA ||
		ma == OTG_USB3_900MA ||
		ma == OTG_DEVICE_RESUME) {
		otg_dbg(otg, "cancel discon work\n");
		__cancel_delayed_work(&data->suspend_discon_work);
	} else if (ma == OTG_DEVICE_SUSPEND) {
		otg_dbg(otg, "schedule discon work\n");
		schedule_delayed_work(&data->suspend_discon_work,
				SUSPEND_DISCONNECT_TIMEOUT);
	}

	/* Needn't notify charger capability if charger_detection disable */
	if (!charger_detect_enable(otg) && !sdp_charging(otg))
		return 0;

	if (ma == OTG_DEVICE_SUSPEND) {
		spin_lock_irqsave(&otg->lock, flags);
		cap.chrg_type = otg->charging_cap.chrg_type;
		cap.ma = otg->charging_cap.ma;
		cap.chrg_evt = POWER_SUPPLY_CHARGER_EVENT_SUSPEND;
		spin_unlock_irqrestore(&otg->lock, flags);

		/* ma is zero mean D+/D- opened cable.
		 * If SMIP set, then notify 500ma.
		 * Otherwise, notify 0ma.
		*/
		if (!cap.ma) {
			if (data->charging_compliance) {
				cap.ma = 500;
				cap.chrg_evt =
					POWER_SUPPLY_CHARGER_EVENT_CONNECT;
			}
		/* For standard SDP, if SMIP set, then ignore suspend */
		} else if (data->charging_compliance)
			return 0;
		/* Stander SDP(cap.ma != 0) and SMIP not set.
		 * Should send 0ma with SUSPEND event
		 */
		else
			cap.ma = 2;

		if (sdp_charging(otg))
			atomic_notifier_call_chain(&otg->usb2_phy.notifier,
					USB_EVENT_ENUMERATED, &cap.ma);
		else
			atomic_notifier_call_chain(&otg->usb2_phy.notifier,
					USB_EVENT_CHARGER, &cap);
		otg_dbg(otg, "Notify EM	CHARGER_EVENT_SUSPEND\n");

		return 0;
	} else if (ma == OTG_DEVICE_RESUME) {
		otg_dbg(otg, "Notify EM CHARGER_EVENT_CONNECT\n");
		dwc3_intel_byt_notify_charger_type(otg,
				POWER_SUPPLY_CHARGER_EVENT_CONNECT);

		return 0;
	}

	/* For SMIP set case, only need to report 500/900ma */
	if (data->charging_compliance) {
		if ((ma != OTG_USB2_500MA) &&
				(ma != OTG_USB3_900MA))
			return 0;
	}

	/* Covert macro to integer number*/
	switch (ma) {
	case OTG_USB2_100MA:
		ma = 100;
		break;
	case OTG_USB3_150MA:
		ma = 150;
		break;
	case OTG_USB2_500MA:
		ma = 500;
		break;
	case OTG_USB3_900MA:
		ma = 900;
		break;
	default:
		otg_err(otg, "Device driver set invalid SDP current value!\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&otg->lock, flags);
	otg->charging_cap.ma = ma;
	spin_unlock_irqrestore(&otg->lock, flags);

	dwc3_intel_byt_notify_charger_type(otg,
			POWER_SUPPLY_CHARGER_EVENT_CONNECT);

	return 0;
}