コード例 #1
0
ファイル: ezx-pcap.c プロジェクト: 19Dan01/linux
static void pcap_isr_work(struct work_struct *work)
{
	struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
	struct pcap_platform_data *pdata = dev_get_platdata(&pcap->spi->dev);
	u32 msr, isr, int_sel, service;
	int irq;

	do {
		ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
		ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);

		/* We can't service/ack irqs that are assigned to port 2 */
		if (!(pdata->config & PCAP_SECOND_PORT)) {
			ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
			isr &= ~int_sel;
		}

		ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
		ezx_pcap_write(pcap, PCAP_REG_ISR, isr);

		local_irq_disable();
		service = isr & ~msr;
		for (irq = pcap->irq_base; service; service >>= 1, irq++) {
			if (service & 1)
				generic_handle_irq(irq);
		}
		local_irq_enable();
		ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
	} while (gpio_get_value(pdata->gpio));
}
コード例 #2
0
ファイル: ezx-pcap.c プロジェクト: 19Dan01/linux
static void pcap_adc_trigger(struct pcap_chip *pcap)
{
	u32 tmp;
	u8 head;

	mutex_lock(&pcap->adc_mutex);
	head = pcap->adc_head;
	if (!pcap->adc_queue[head]) {
		/* queue is empty, save power */
		pcap_disable_adc(pcap);
		mutex_unlock(&pcap->adc_mutex);
		return;
	}
	/* start conversion on requested bank, save TS_M bits */
	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
	tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
	tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;

	if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1)
		tmp |= PCAP_ADC_AD_SEL1;

	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
	mutex_unlock(&pcap->adc_mutex);
	ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
}
コード例 #3
0
ファイル: rtc-pcap.c プロジェクト: AlexShiLucky/linux
static int pcap_rtc_read_time(struct device *dev, struct rtc_time *tm)
{
	struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
	unsigned long secs;
	u32 tod, days;

	ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_TOD, &tod);
	secs = tod & PCAP_RTC_TOD_MASK;

	ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_DAY, &days);
	secs += (days & PCAP_RTC_DAY_MASK) * SEC_PER_DAY;

	rtc_time_to_tm(secs, tm);

	return 0;
}
コード例 #4
0
static void pcap_adc_trigger(struct pcap_chip *pcap)
{
	u32 tmp;
	u8 head;

	mutex_lock(&pcap->adc_mutex);
	head = pcap->adc_head;
	if (!pcap->adc_queue[head]) {
		
		pcap_disable_adc(pcap);
		mutex_unlock(&pcap->adc_mutex);
		return;
	}
	
	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
	tmp &= (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
	tmp |= pcap->adc_queue[head]->flags | PCAP_ADC_ADEN;

	if (pcap->adc_queue[head]->bank == PCAP_ADC_BANK_1)
		tmp |= PCAP_ADC_AD_SEL1;

	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
	mutex_unlock(&pcap->adc_mutex);
	ezx_pcap_write(pcap, PCAP_REG_ADR, PCAP_ADR_ASC);
}
コード例 #5
0
ファイル: ezx-pcap.c プロジェクト: 19Dan01/linux
static void pcap_disable_adc(struct pcap_chip *pcap)
{
	u32 tmp;

	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
	tmp &= ~(PCAP_ADC_ADEN|PCAP_ADC_BATT_I_ADC|PCAP_ADC_BATT_I_POLARITY);
	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
}
コード例 #6
0
ファイル: rtc-pcap.c プロジェクト: AlexShiLucky/linux
static int pcap_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
{
	struct pcap_rtc *pcap_rtc = dev_get_drvdata(dev);
	struct rtc_time *tm = &alrm->time;
	unsigned long secs;
	u32 tod;	/* time of day, seconds since midnight */
	u32 days;	/* days since 1/1/1970 */

	ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_TODA, &tod);
	secs = tod & PCAP_RTC_TOD_MASK;

	ezx_pcap_read(pcap_rtc->pcap, PCAP_REG_RTC_DAYA, &days);
	secs += (days & PCAP_RTC_DAY_MASK) * SEC_PER_DAY;

	rtc_time_to_tm(secs, tm);

	return 0;
}
コード例 #7
0
ファイル: ezx-pcap.c プロジェクト: 19Dan01/linux
/* ADC */
void pcap_set_ts_bits(struct pcap_chip *pcap, u32 bits)
{
	u32 tmp;

	mutex_lock(&pcap->adc_mutex);
	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
	tmp &= ~(PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
	tmp |= bits & (PCAP_ADC_TS_M_MASK | PCAP_ADC_TS_REF_LOWPWR);
	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
	mutex_unlock(&pcap->adc_mutex);
}
コード例 #8
0
ファイル: ezx-pcap.c プロジェクト: 12rafael/jellytimekernel
static void pcap_isr_work(struct work_struct *work)
{
	struct pcap_chip *pcap = container_of(work, struct pcap_chip, isr_work);
	struct pcap_platform_data *pdata = pcap->spi->dev.platform_data;
	u32 msr, isr, int_sel, service;
	int irq;

	do {
		ezx_pcap_read(pcap, PCAP_REG_MSR, &msr);
		ezx_pcap_read(pcap, PCAP_REG_ISR, &isr);

		/* We cant service/ack irqs that are assigned to port 2 */
		if (!(pdata->config & PCAP_SECOND_PORT)) {
			ezx_pcap_read(pcap, PCAP_REG_INT_SEL, &int_sel);
			isr &= ~int_sel;
		}

		ezx_pcap_write(pcap, PCAP_REG_MSR, isr | msr);
		ezx_pcap_write(pcap, PCAP_REG_ISR, isr);

		local_irq_disable();
		service = isr & ~msr;
		for (irq = pcap->irq_base; service; service >>= 1, irq++) {
			if (service & 1) {
				struct irq_desc *desc = irq_to_desc(irq);

				if (WARN(!desc, KERN_WARNING
						"Invalid PCAP IRQ %d\n", irq))
					break;

				if (desc->status & IRQ_DISABLED)
					note_interrupt(irq, desc, IRQ_NONE);
				else
					desc->handle_irq(irq, desc);
			}
		}
		local_irq_enable();
		ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr);
	} while (gpio_get_value(irq_to_gpio(pcap->spi->irq)));
}
コード例 #9
0
ファイル: ezx-pcap.c プロジェクト: 19Dan01/linux
static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
{
	struct pcap_chip *pcap = _pcap;
	struct pcap_adc_request *req;
	u16 res[2];
	u32 tmp;

	mutex_lock(&pcap->adc_mutex);
	req = pcap->adc_queue[pcap->adc_head];

	if (WARN(!req, "adc irq without pending request\n")) {
		mutex_unlock(&pcap->adc_mutex);
		return IRQ_HANDLED;
	}

	/* read requested channels results */
	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
	tmp &= ~(PCAP_ADC_ADA1_MASK | PCAP_ADC_ADA2_MASK);
	tmp |= (req->ch[0] << PCAP_ADC_ADA1_SHIFT);
	tmp |= (req->ch[1] << PCAP_ADC_ADA2_SHIFT);
	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
	ezx_pcap_read(pcap, PCAP_REG_ADR, &tmp);
	res[0] = (tmp & PCAP_ADR_ADD1_MASK) >> PCAP_ADR_ADD1_SHIFT;
	res[1] = (tmp & PCAP_ADR_ADD2_MASK) >> PCAP_ADR_ADD2_SHIFT;

	pcap->adc_queue[pcap->adc_head] = NULL;
	pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
	mutex_unlock(&pcap->adc_mutex);

	/* pass the results and release memory */
	req->callback(req->data, res);
	kfree(req);

	/* trigger next conversion (if any) on queue */
	pcap_adc_trigger(pcap);

	return IRQ_HANDLED;
}
コード例 #10
0
static irqreturn_t pcap_adc_irq(int irq, void *_pcap)
{
	struct pcap_chip *pcap = _pcap;
	struct pcap_adc_request *req;
	u16 res[2];
	u32 tmp;

	mutex_lock(&pcap->adc_mutex);
	req = pcap->adc_queue[pcap->adc_head];

	if (WARN(!req, KERN_WARNING "adc irq without pending request\n")) {
		mutex_unlock(&pcap->adc_mutex);
		return IRQ_HANDLED;
	}

	
	ezx_pcap_read(pcap, PCAP_REG_ADC, &tmp);
	tmp &= ~(PCAP_ADC_ADA1_MASK | PCAP_ADC_ADA2_MASK);
	tmp |= (req->ch[0] << PCAP_ADC_ADA1_SHIFT);
	tmp |= (req->ch[1] << PCAP_ADC_ADA2_SHIFT);
	ezx_pcap_write(pcap, PCAP_REG_ADC, tmp);
	ezx_pcap_read(pcap, PCAP_REG_ADR, &tmp);
	res[0] = (tmp & PCAP_ADR_ADD1_MASK) >> PCAP_ADR_ADD1_SHIFT;
	res[1] = (tmp & PCAP_ADR_ADD2_MASK) >> PCAP_ADR_ADD2_SHIFT;

	pcap->adc_queue[pcap->adc_head] = NULL;
	pcap->adc_head = (pcap->adc_head + 1) & (PCAP_ADC_MAXQ - 1);
	mutex_unlock(&pcap->adc_mutex);

	
	req->callback(req->data, res);
	kfree(req);

	
	pcap_adc_trigger(pcap);

	return IRQ_HANDLED;
}
コード例 #11
0
/* PCAP2 interrupts us on keypress */
static irqreturn_t pcap_keys_handler(int irq, void *_pcap_keys)
{
	struct pcap_keys *pcap_keys = _pcap_keys;
	int pirq = irq_to_pcap(pcap_keys->pcap, irq);
	u32 pstat;

	ezx_pcap_read(pcap_keys->pcap, PCAP_REG_PSTAT, &pstat);
	pstat &= 1 << pirq;

	switch (pirq) {
	case PCAP_IRQ_ONOFF:
		input_report_key(pcap_keys->input, KEY_POWER, !pstat);
		break;
	case PCAP_IRQ_MIC:
		input_report_key(pcap_keys->input, KEY_HP, !pstat);
		break;
	}

	input_sync(pcap_keys->input);

	return IRQ_HANDLED;
}