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 + -
显示快捷键?