⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cbus.c

📁 xen虚拟机源代码安装包
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * CBUS three-pin bus and the Retu / Betty / Tahvo / Vilma / Avilma / * Hinku / Vinku / Ahne / Pihi chips used in various Nokia platforms. * Based on reverse-engineering of a linux driver. * * Copyright (C) 2008 Nokia Corporation * Written by Andrzej Zaborowski <andrew@openedhand.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 or * (at your option) version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include "qemu-common.h"#include "irq.h"#include "devices.h"#include "sysemu.h"//#define DEBUGstruct cbus_slave_s;struct cbus_priv_s {    struct cbus_s cbus;    int sel;    int dat;    int clk;    int bit;    int dir;    uint16_t val;    qemu_irq dat_out;    int addr;    int reg;    int rw;    enum {        cbus_address,        cbus_value,    } cycle;    struct cbus_slave_s *slave[8];};struct cbus_slave_s {    void *opaque;    void (*io)(void *opaque, int rw, int reg, uint16_t *val);    int addr;};static void cbus_io(struct cbus_priv_s *s){    if (s->slave[s->addr])        s->slave[s->addr]->io(s->slave[s->addr]->opaque,                        s->rw, s->reg, &s->val);    else        cpu_abort(cpu_single_env, "%s: bad slave address %i\n",                        __FUNCTION__, s->addr);}static void cbus_cycle(struct cbus_priv_s *s){    switch (s->cycle) {    case cbus_address:        s->addr = (s->val >> 6) & 7;        s->rw =   (s->val >> 5) & 1;        s->reg =  (s->val >> 0) & 0x1f;        s->cycle = cbus_value;        s->bit = 15;        s->dir = !s->rw;        s->val = 0;        if (s->rw)            cbus_io(s);        break;    case cbus_value:        if (!s->rw)            cbus_io(s);        s->cycle = cbus_address;        s->bit = 8;        s->dir = 1;        s->val = 0;        break;    }}static void cbus_clk(void *opaque, int line, int level){    struct cbus_priv_s *s = (struct cbus_priv_s *) opaque;    if (!s->sel && level && !s->clk) {        if (s->dir)            s->val |= s->dat << (s->bit --);        else            qemu_set_irq(s->dat_out, (s->val >> (s->bit --)) & 1);        if (s->bit < 0)            cbus_cycle(s);    }    s->clk = level;}static void cbus_dat(void *opaque, int line, int level){    struct cbus_priv_s *s = (struct cbus_priv_s *) opaque;    s->dat = level;}static void cbus_sel(void *opaque, int line, int level){    struct cbus_priv_s *s = (struct cbus_priv_s *) opaque;    if (!level) {        s->dir = 1;        s->bit = 8;        s->val = 0;    }    s->sel = level;}struct cbus_s *cbus_init(qemu_irq dat){    struct cbus_priv_s *s = (struct cbus_priv_s *) qemu_mallocz(sizeof(*s));    s->dat_out = dat;    s->cbus.clk = qemu_allocate_irqs(cbus_clk, s, 1)[0];    s->cbus.dat = qemu_allocate_irqs(cbus_dat, s, 1)[0];    s->cbus.sel = qemu_allocate_irqs(cbus_sel, s, 1)[0];    s->sel = 1;    s->clk = 0;    s->dat = 0;    return &s->cbus;}void cbus_attach(struct cbus_s *bus, void *slave_opaque){    struct cbus_slave_s *slave = (struct cbus_slave_s *) slave_opaque;    struct cbus_priv_s *s = (struct cbus_priv_s *) bus;    s->slave[slave->addr] = slave;}/* Retu/Vilma */struct cbus_retu_s {    uint16_t irqst;    uint16_t irqen;    uint16_t cc[2];    int channel;    uint16_t result[16];    uint16_t sample;    uint16_t status;    struct {        uint16_t cal;    } rtc;    int is_vilma;    qemu_irq irq;    struct cbus_slave_s cbus;};static void retu_interrupt_update(struct cbus_retu_s *s){    qemu_set_irq(s->irq, s->irqst & ~s->irqen);}#define RETU_REG_ASICR		0x00	/* (RO) ASIC ID & revision */#define RETU_REG_IDR		0x01	/* (T)  Interrupt ID */#define RETU_REG_IMR		0x02	/* (RW) Interrupt mask */#define RETU_REG_RTCDSR		0x03	/* (RW) RTC seconds register */#define RETU_REG_RTCHMR		0x04	/* (RO) RTC hours and minutes reg */#define RETU_REG_RTCHMAR	0x05	/* (RW) RTC hours and minutes set reg */#define RETU_REG_RTCCALR	0x06	/* (RW) RTC calibration register */#define RETU_REG_ADCR		0x08	/* (RW) ADC result register */#define RETU_REG_ADCSCR		0x09	/* (RW) ADC sample control register */#define RETU_REG_AFCR		0x0a	/* (RW) AFC register */#define RETU_REG_ANTIFR		0x0b	/* (RW) AntiF register */#define RETU_REG_CALIBR		0x0c	/* (RW) CalibR register*/#define RETU_REG_CCR1		0x0d	/* (RW) Common control register 1 */#define RETU_REG_CCR2		0x0e	/* (RW) Common control register 2 */#define RETU_REG_RCTRL_CLR	0x0f	/* (T)  Regulator clear register */#define RETU_REG_RCTRL_SET	0x10	/* (T)  Regulator set register */#define RETU_REG_TXCR		0x11	/* (RW) TxC register */#define RETU_REG_STATUS		0x16	/* (RO) Status register */#define RETU_REG_WATCHDOG	0x17	/* (RW) Watchdog register */#define RETU_REG_AUDTXR		0x18	/* (RW) Audio Codec Tx register */#define RETU_REG_AUDPAR		0x19	/* (RW) AudioPA register */#define RETU_REG_AUDRXR1	0x1a	/* (RW) Audio receive register 1 */#define RETU_REG_AUDRXR2	0x1b	/* (RW) Audio receive register 2 */#define RETU_REG_SGR1		0x1c	/* (RW) */#define RETU_REG_SCR1		0x1d	/* (RW) */#define RETU_REG_SGR2		0x1e	/* (RW) */#define RETU_REG_SCR2		0x1f	/* (RW) *//* Retu Interrupt sources */enum {    retu_int_pwr	= 0,	/* Power button */    retu_int_char	= 1,	/* Charger */    retu_int_rtcs	= 2,	/* Seconds */    retu_int_rtcm	= 3,	/* Minutes */    retu_int_rtcd	= 4,	/* Days */    retu_int_rtca	= 5,	/* Alarm */    retu_int_hook	= 6,	/* Hook */    retu_int_head	= 7,	/* Headset */    retu_int_adcs	= 8,	/* ADC sample */};/* Retu ADC channel wiring */enum {    retu_adc_bsi	= 1,	/* BSI */    retu_adc_batt_temp	= 2,	/* Battery temperature */    retu_adc_chg_volt	= 3,	/* Charger voltage */    retu_adc_head_det	= 4,	/* Headset detection */    retu_adc_hook_det	= 5,	/* Hook detection */    retu_adc_rf_gp	= 6,	/* RF GP */    retu_adc_tx_det	= 7,	/* Wideband Tx detection */    retu_adc_batt_volt	= 8,	/* Battery voltage */    retu_adc_sens	= 10,	/* Light sensor */    retu_adc_sens_temp	= 11,	/* Light sensor temperature */    retu_adc_bbatt_volt	= 12,	/* Backup battery voltage */    retu_adc_self_temp	= 13,	/* RETU temperature */};static inline uint16_t retu_read(struct cbus_retu_s *s, int reg){#ifdef DEBUG    printf("RETU read at %02x\n", reg);#endif    switch (reg) {    case RETU_REG_ASICR:        return 0x0215 | (s->is_vilma << 7);    case RETU_REG_IDR:	/* TODO: Or is this ffs(s->irqst)?  */        return s->irqst;    case RETU_REG_IMR:        return s->irqen;    case RETU_REG_RTCDSR:    case RETU_REG_RTCHMR:    case RETU_REG_RTCHMAR:        /* TODO */        return 0x0000;    case RETU_REG_RTCCALR:        return s->rtc.cal;    case RETU_REG_ADCR:        return (s->channel << 10) | s->result[s->channel];    case RETU_REG_ADCSCR:        return s->sample;    case RETU_REG_AFCR:    case RETU_REG_ANTIFR:    case RETU_REG_CALIBR:        /* TODO */        return 0x0000;    case RETU_REG_CCR1:        return s->cc[0];    case RETU_REG_CCR2:        return s->cc[1];    case RETU_REG_RCTRL_CLR:    case RETU_REG_RCTRL_SET:    case RETU_REG_TXCR:        /* TODO */        return 0x0000;    case RETU_REG_STATUS:        return s->status;    case RETU_REG_WATCHDOG:    case RETU_REG_AUDTXR:    case RETU_REG_AUDPAR:    case RETU_REG_AUDRXR1:    case RETU_REG_AUDRXR2:    case RETU_REG_SGR1:    case RETU_REG_SCR1:    case RETU_REG_SGR2:    case RETU_REG_SCR2:        /* TODO */        return 0x0000;    default:        cpu_abort(cpu_single_env, "%s: bad register %02x\n",                        __FUNCTION__, reg);    }}static inline void retu_write(struct cbus_retu_s *s, int reg, uint16_t val){#ifdef DEBUG    printf("RETU write of %04x at %02x\n", val, reg);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -