nseries.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 1,146 行 · 第 1/3 页

C
1,146
字号
/* * Nokia N-series internet tablets. * * Copyright (C) 2007 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 "sysemu.h"#include "omap.h"#include "arm-misc.h"#include "irq.h"#include "console.h"#include "boards.h"#include "i2c.h"#include "devices.h"#include "flash.h"#include "hw.h"/* Nokia N8x0 support */struct n800_s {    struct omap_mpu_state_s *cpu;    struct rfbi_chip_s blizzard;    struct {        void *opaque;        uint32_t (*txrx)(void *opaque, uint32_t value, int len);        struct uwire_slave_s *chip;    } ts;    i2c_bus *i2c;    int keymap[0x80];    i2c_slave *kbd;    struct tusb_s *usb;    void *retu;    void *tahvo;};/* GPIO pins */#define N8X0_TUSB_ENABLE_GPIO		0#define N800_MMC2_WP_GPIO		8#define N800_UNKNOWN_GPIO0		9	/* out */#define N800_UNKNOWN_GPIO1		10	/* out */#define N800_CAM_TURN_GPIO		12#define N810_GPS_RESET_GPIO		12#define N800_BLIZZARD_POWERDOWN_GPIO	15#define N800_MMC1_WP_GPIO		23#define N8X0_ONENAND_GPIO		26#define N810_BLIZZARD_RESET_GPIO	30#define N800_UNKNOWN_GPIO2		53	/* out */#define N8X0_TUSB_INT_GPIO		58#define N8X0_BT_WKUP_GPIO		61#define N8X0_STI_GPIO			62#define N8X0_CBUS_SEL_GPIO		64#define N8X0_CBUS_DAT_GPIO		65#define N8X0_CBUS_CLK_GPIO		66#define N8X0_WLAN_IRQ_GPIO		87#define N8X0_BT_RESET_GPIO		92#define N8X0_TEA5761_CS_GPIO		93#define N800_UNKNOWN_GPIO		94#define N810_TSC_RESET_GPIO		94#define N800_CAM_ACT_GPIO		95#define N810_GPS_WAKEUP_GPIO		95#define N8X0_MMC_CS_GPIO		96#define N8X0_WLAN_PWR_GPIO		97#define N8X0_BT_HOST_WKUP_GPIO		98#define N800_UNKNOWN_GPIO3		101	/* out */#define N810_KB_LOCK_GPIO		102#define N800_TSC_TS_GPIO		103#define N810_TSC_TS_GPIO		106#define N8X0_HEADPHONE_GPIO		107#define N8X0_RETU_GPIO			108#define N800_TSC_KP_IRQ_GPIO		109#define N810_KEYBOARD_GPIO		109#define N800_BAT_COVER_GPIO		110#define N810_SLIDE_GPIO			110#define N8X0_TAHVO_GPIO			111#define N800_UNKNOWN_GPIO4		112	/* out */#define N810_SLEEPX_LED_GPIO		112#define N800_TSC_RESET_GPIO		118	/* ? */#define N800_TSC_UNKNOWN_GPIO		119	/* out */#define N8X0_TMP105_GPIO		125/* Config */#define XLDR_LL_UART			1/* Addresses on the I2C bus 0 */#define N810_TLV320AIC33_ADDR		0x18	/* Audio CODEC */#define N8X0_TCM825x_ADDR		0x29	/* Camera */#define N810_LP5521_ADDR		0x32	/* LEDs */#define N810_TSL2563_ADDR		0x3d	/* Light sensor */#define N810_LM8323_ADDR		0x45	/* Keyboard *//* Addresses on the I2C bus 1 */#define N8X0_TMP105_ADDR		0x48	/* Temperature sensor */#define N8X0_MENELAUS_ADDR		0x72	/* Power management *//* Chipselects on GPMC NOR interface */#define N8X0_ONENAND_CS			0#define N8X0_USB_ASYNC_CS		1#define N8X0_USB_SYNC_CS		4static void n800_mmc_cs_cb(void *opaque, int line, int level){    /* TODO: this seems to actually be connected to the menelaus, to     * which also both MMC slots connect.  */    omap_mmc_enable((struct omap_mmc_s *) opaque, !level);    printf("%s: MMC slot %i active\n", __FUNCTION__, level + 1);}static void n8x0_gpio_setup(struct n800_s *s){    qemu_irq *mmc_cs = qemu_allocate_irqs(n800_mmc_cs_cb, s->cpu->mmc, 1);    omap2_gpio_out_set(s->cpu->gpif, N8X0_MMC_CS_GPIO, mmc_cs[0]);    qemu_irq_lower(omap2_gpio_in_get(s->cpu->gpif, N800_BAT_COVER_GPIO)[0]);}static void n8x0_nand_setup(struct n800_s *s){    /* Either ec40xx or ec48xx are OK for the ID */    omap_gpmc_attach(s->cpu->gpmc, N8X0_ONENAND_CS, 0, onenand_base_update,                    onenand_base_unmap,                    onenand_init(0xec4800, 1,                            omap2_gpio_in_get(s->cpu->gpif,                                    N8X0_ONENAND_GPIO)[0]));}static void n8x0_i2c_setup(struct n800_s *s){    qemu_irq tmp_irq = omap2_gpio_in_get(s->cpu->gpif, N8X0_TMP105_GPIO)[0];    /* Attach the CPU on one end of our I2C bus.  */    s->i2c = omap_i2c_bus(s->cpu->i2c[0]);    /* Attach a menelaus PM chip */    i2c_set_slave_address(                    twl92230_init(s->i2c,                            s->cpu->irq[0][OMAP_INT_24XX_SYS_NIRQ]),                    N8X0_MENELAUS_ADDR);    /* Attach a TMP105 PM chip (A0 wired to ground) */    i2c_set_slave_address(tmp105_init(s->i2c, tmp_irq), N8X0_TMP105_ADDR);}/* Touchscreen and keypad controller */static struct mouse_transform_info_s n800_pointercal = {    .x = 800,    .y = 480,    .a = { 14560, -68, -3455208, -39, -9621, 35152972, 65536 },};static struct mouse_transform_info_s n810_pointercal = {    .x = 800,    .y = 480,    .a = { 15041, 148, -4731056, 171, -10238, 35933380, 65536 },};#define RETU_KEYCODE	61	/* F3 */static void n800_key_event(void *opaque, int keycode){    struct n800_s *s = (struct n800_s *) opaque;    int code = s->keymap[keycode & 0x7f];    if (code == -1) {        if ((keycode & 0x7f) == RETU_KEYCODE)            retu_key_event(s->retu, !(keycode & 0x80));        return;    }    tsc210x_key_event(s->ts.chip, code, !(keycode & 0x80));}static const int n800_keys[16] = {    -1,    72,	/* Up */    63,	/* Home (F5) */    -1,    75,	/* Left */    28,	/* Enter */    77,	/* Right */    -1,     1,	/* Cycle (ESC) */    80,	/* Down */    62,	/* Menu (F4) */    -1,    66,	/* Zoom- (F8) */    64,	/* FullScreen (F6) */    65,	/* Zoom+ (F7) */    -1,};static void n800_tsc_kbd_setup(struct n800_s *s){    int i;    /* XXX: are the three pins inverted inside the chip between the     * tsc and the cpu (N4111)?  */    qemu_irq penirq = 0;	/* NC */    qemu_irq kbirq = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_KP_IRQ_GPIO)[0];    qemu_irq dav = omap2_gpio_in_get(s->cpu->gpif, N800_TSC_TS_GPIO)[0];    s->ts.chip = tsc2301_init(penirq, kbirq, dav, 0);    s->ts.opaque = s->ts.chip->opaque;    s->ts.txrx = tsc210x_txrx;    for (i = 0; i < 0x80; i ++)        s->keymap[i] = -1;    for (i = 0; i < 0x10; i ++)        if (n800_keys[i] >= 0)            s->keymap[n800_keys[i]] = i;    qemu_add_kbd_event_handler(n800_key_event, s);    tsc210x_set_transform(s->ts.chip, &n800_pointercal);}static void n810_tsc_setup(struct n800_s *s){    qemu_irq pintdav = omap2_gpio_in_get(s->cpu->gpif, N810_TSC_TS_GPIO)[0];    s->ts.opaque = tsc2005_init(pintdav);    s->ts.txrx = tsc2005_txrx;    tsc2005_set_transform(s->ts.opaque, &n810_pointercal);}/* N810 Keyboard controller */static void n810_key_event(void *opaque, int keycode){    struct n800_s *s = (struct n800_s *) opaque;    int code = s->keymap[keycode & 0x7f];    if (code == -1) {        if ((keycode & 0x7f) == RETU_KEYCODE)            retu_key_event(s->retu, !(keycode & 0x80));        return;    }    lm832x_key_event(s->kbd, code, !(keycode & 0x80));}#define M	0static int n810_keys[0x80] = {    [0x01] = 16,	/* Q */    [0x02] = 37,	/* K */    [0x03] = 24,	/* O */    [0x04] = 25,	/* P */    [0x05] = 14,	/* Backspace */    [0x06] = 30,	/* A */    [0x07] = 31,	/* S */    [0x08] = 32,	/* D */    [0x09] = 33,	/* F */    [0x0a] = 34,	/* G */    [0x0b] = 35,	/* H */    [0x0c] = 36,	/* J */    [0x11] = 17,	/* W */    [0x12] = 62,	/* Menu (F4) */    [0x13] = 38,	/* L */    [0x14] = 40,	/* ' (Apostrophe) */    [0x16] = 44,	/* Z */    [0x17] = 45,	/* X */    [0x18] = 46,	/* C */    [0x19] = 47,	/* V */    [0x1a] = 48,	/* B */    [0x1b] = 49,	/* N */    [0x1c] = 42,	/* Shift (Left shift) */    [0x1f] = 65,	/* Zoom+ (F7) */    [0x21] = 18,	/* E */    [0x22] = 39,	/* ; (Semicolon) */    [0x23] = 12,	/* - (Minus) */    [0x24] = 13,	/* = (Equal) */    [0x2b] = 56,	/* Fn (Left Alt) */    [0x2c] = 50,	/* M */    [0x2f] = 66,	/* Zoom- (F8) */    [0x31] = 19,	/* R */    [0x32] = 29 | M,	/* Right Ctrl */    [0x34] = 57,	/* Space */    [0x35] = 51,	/* , (Comma) */    [0x37] = 72 | M,	/* Up */    [0x3c] = 82 | M,	/* Compose (Insert) */    [0x3f] = 64,	/* FullScreen (F6) */    [0x41] = 20,	/* T */    [0x44] = 52,	/* . (Dot) */    [0x46] = 77 | M,	/* Right */    [0x4f] = 63,	/* Home (F5) */    [0x51] = 21,	/* Y */    [0x53] = 80 | M,	/* Down */    [0x55] = 28,	/* Enter */    [0x5f] =  1,	/* Cycle (ESC) */    [0x61] = 22,	/* U */    [0x64] = 75 | M,	/* Left */    [0x71] = 23,	/* I */#if 0    [0x75] = 28 | M,	/* KP Enter (KP Enter) */#else    [0x75] = 15,	/* KP Enter (Tab) */#endif};#undef Mstatic void n810_kbd_setup(struct n800_s *s){    qemu_irq kbd_irq = omap2_gpio_in_get(s->cpu->gpif, N810_KEYBOARD_GPIO)[0];    int i;    for (i = 0; i < 0x80; i ++)        s->keymap[i] = -1;    for (i = 0; i < 0x80; i ++)        if (n810_keys[i] > 0)            s->keymap[n810_keys[i]] = i;    qemu_add_kbd_event_handler(n810_key_event, s);    /* Attach the LM8322 keyboard to the I2C bus,     * should happen in n8x0_i2c_setup and s->kbd be initialised here.  */    s->kbd = lm8323_init(s->i2c, kbd_irq);    i2c_set_slave_address(s->kbd, N810_LM8323_ADDR);}/* LCD MIPI DBI-C controller (URAL) */struct mipid_s {    int resp[4];    int param[4];    int p;    int pm;    int cmd;    int sleep;    int booster;    int te;    int selfcheck;    int partial;    int normal;    int vscr;    int invert;    int onoff;    int gamma;    uint32_t id;};static void mipid_reset(struct mipid_s *s){    if (!s->sleep)        fprintf(stderr, "%s: Display off\n", __FUNCTION__);    s->pm = 0;    s->cmd = 0;    s->sleep = 1;    s->booster = 0;    s->selfcheck =            (1 << 7) |	/* Register loading OK.  */            (1 << 5) |	/* The chip is attached.  */            (1 << 4);	/* Display glass still in one piece.  */    s->te = 0;    s->partial = 0;

⌨️ 快捷键说明

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