mt6577驱动开发 笔记版 转载请注明出处---crosskernel@gmail.com
                                                            生活随笔
收集整理的這篇文章主要介紹了
                                mt6577驱动开发                      笔记版  转载请注明出处---crosskernel@gmail.com
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.                        
                                
 
 
 
3 Preloader & Uboot
3.1 Preloader3.1.1Preloader結構
Preloader的主題結構在文件:“alps\mediatek\platform\mt6577\preloader\src\core\main.c”中。
void main(void)
{
//時鐘、uart、mcp等初始化
bldr_pre_process();
…
bldr_handshake(&handler);
…
//這里加載DSP 3G AP的ROM。
…
#if CFG_LOAD_UBOOT
addr = CFG_UBOOT_MEMADDR;
//加載uboot
? ? if (bldr_load_part(PART_UBOOT, bootdev, &addr) != 0)
? ? ? ? goto error;
#endif
…
//跳轉到uboot
bldr_jump(addr, BOOT_ARGUMENT_ADDR, sizeof(boot_arg_t));
…
}
3.1.2 PLL與Clock
PLL介紹在datasheet 1190
Pll.c中“void mt6577_pll_init(void)”
似乎PLL主要是在preloader里打開的。
//設置的PLL
void mt6577_pll_init(void)
{
}
//根據MCP的型號設置DDR相關時鐘
int mt6577_pll_init2 (void)
{
if (mt6577_get_dram_type() == 2)
? ? {
? ? ? ?…
? ? }
? ? else if (mt6577_get_dram_type() == 3)
{
…
? ? }
}
3.1.3 DDR的初始化
EMI_SETTINGS emi_settings[]里面定義了KMNJS000ZM_B205 H9TP32A4GDMCPR KMSJS000KM_B308等類型的MCP的配置參數。
在“void mt6577_set_emi (void)”里面會根據“emi_settings[]”的配置初始化MCP控制器。
3.1.4 鏡像布局與加載
鏡像布局參數被存放在文件:
mediatek/custom/out/mt6577preloader/cust_part.c里
static part_t platform_parts[PART_MAX_COUNT];里面記錄每個鏡像的長度。
在mediatek/platform/mt6577/preloader/src/core/part.c里
函數int part_init(void)里,依次累加前面所有鏡像,算出當前鏡像的起始位置。
3.1.5 EMMC 驅動
#define MMC_HOST_ID ?0
u32 mmc_init_device(void)
{…
//emmc 零通道
ret = mmc_init(MMC_HOST_ID);
…
}
//分別初始化host和card
int mmc_init(int id)
{ ??
? ? …
? ? host = &sd_host[id];
? ? card = &sd_card[id];
? ? err = mmc_init_host(host, id);
? ? if (err == MMC_ERR_NONE)
? ? ? ? err = mmc_init_card(host, card);
…
}
//host初始化
int mmc_init_host(struct mmc_host *host, int id)
{
? ? memset(host, 0, sizeof(struct mmc_host));
? ? return msdc_init(host, id);
}
/*
#define MSDC0_BASE ? ? ? ? ?(IO_PHYS + 0x01220000)
#define MSDC1_BASE ? ? ? ? ?(IO_PHYS + 0x01230000)
#define MSDC2_BASE ? ? ? ? ?(IO_PHYS + 0x01250000)
#define MSDC3_BASE ? ? ? ? ?(IO_PHYS + 0x01240000)
#define IO_PHYS ? ? ? ? ? ? 0xC0000000
對于通道0,基地址在MSDC0_BASE即為0xC1220000。其余通道基地址在0xC1230000 0xC1240000 ?0xC1250000,但是datasheet里只有0通道0xC1220000的信息。
*/
int msdc_init(struct mmc_host *host, int id)
{
u32 baddr[] = {MSDC0_BASE, MSDC1_BASE, MSDC2_BASE, MSDC3_BASE};
//基地址選擇0通道
? ? u32 base = baddr[id];
? ? //0通道
host->id ? ? = id;
//基地址
? ? host->base ? = base;
host->f_max ?= MSDC_MAX_SCLK;
…
//以下所有對0通道的寄存器操作都是基于這基地址“base”進行的
}
3.3 uboot
Uboot代碼:
Generic部分:
Uboot的generic的部分位于“bootable/bootloader/uboot/”
Mt6577相關部分相關位于:
mediatek/platform/mt6577/uboot/
mediatek/custom/out/mt6577/uboot/
uboot的config:
“alps\mediatek\custom\out\mt6577\uboot\inc\configs\ubconfigs.h”
3.3.1 uboot初始化流程
Uboot初始化主體位于“bootable/bootloader/uboot/arch/arm/lib/board.c”
void start_armboot (void)
{
…
//執行初始化例程數組
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr)?
{
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
…
//執行平臺相關misc初始化
#if defined(CONFIG_MISC_INIT_R)
/* miscellaneous platform dependent initialisations */
misc_init_r ();
#endif
}
在“bootable/bootloader/uboot/arch/arm/lib/board.c”定義了初始化例程指針數組,其中的各項例程不同的板卡有自己不同的實現:
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
dram_init, ? ? ? ? ? ? ?/* configure available RAM banks */ /* ?change the original init order */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
? ? …
display_dram_config,
NULL,
};
Mt6577的初始化例程的實現位于“mediatek/platform/mt6577/uboot/mt6577_board.c”:
int board_init (void)
{…
mtk_serial_init();
…
mt6577_pinmux_init();s
…
pmic6329_init();
}
3.3.2 鏡像布局與分區
Uboot在“int misc_init_r (…)”里對鏡像分區初始化
int misc_init_r (void)
{…
mt6577_part_init(BLK_NUM(16 * GB));
…
}
/**********************************************************************/
在“mediatek/custom/out/mt6577/uboot/partition.h”里對分區表定義如下:
#include <common.h>
/*該文件可能就是:
“mediatek/custom/out/mt6577/uboot/inc/mt65xx_partition.h”
*/
#include "mt65xx_partition.h"
part_t partition_layout[] = {
{PART_PRELOADER, PART_BLKS_PRELOADER, PART_FLAG_NONE,0},
{PART_DSP_DL, PART_BLKS_DSP_DL, 0, PART_FLAG_NONE},
…
};
3.3.3 gpio初始化
DCT工具產生的“cust_gpio_boot.h”被如下文件:
mediatek/platform/mt6577/uboot/mt6577_gpio_init.c?
默認設置的定義:
u16 gpio_init_mode_data[];
u16 gpio_init_dir_data[];
u16 gpio_init_pullen_data[];
…
設置默認設置
void mt_gpio_set_default(void)
4 Kernel
內核源碼
標準內核:
Alps/kernel
Mtk部分內核
? Alps/mediatek/source/kernel/
? Alps/mediatek/platform/mt6577/kernel
? Alps/mediatek/custom/*/kernel下面也有,如
Alps/mediatek/custom/common/kernel
Alps/mediatek/custom/mt6577/kernel
4.1 ARCH初始化
4.1.1 Board支持
在“alps/mediatek/platform/mt6577/kernel/core/core.c”定義
MACHINE_START(MT6577, "MT6577")
? ? .boot_params ? ?= PHYS_OFFSET + 0x00000100,
? ? .map_io ? ? ? ? = mt6577_map_io,
? ? .init_irq ? ? ? = mt_init_irq,
? ? .timer ? ? ? ? ?= &mt6577_timer,
? ? .init_machine ? = mt6577_init,
? ? .fixup ? ? ? ? ?= mt6577_fixup
MACHINE_END
在“alps/mediatek/platform/mt6577/kernel/core/mt6577_devs.c”注冊device
__init int mt6577_board_init(void)
{
…
retval = platform_device_register(&mt_hid_dev);
retval = platform_device_register(&mt_device_i2c[i]);
retval = platform_device_register(&AudDrv_device);
retval = platform_device_register(&mt6577_device_fb);
retval = platform_device_register(&mtk_hdmi_dev);
retval = platform_device_register(&mt6577_TVOUT_dev);
…
}
在“alps/kernel/mediatek/Makefile”里引用“../../mediatek/build/kernel/Makefile”,該文件即為:“alps/mediatek/build/kernel/Makefile”里面定義了相關的mt6577的內核文件:
machine-y ? ? ? := $(call lc,$(MTK_PLATFORM))
ifeq ($(strip $(KBUILD_OUTPUT_SUPPORT)),yes)
MACHINE ? ? ? ? ?:= mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/core/
machdirs ? ? ? ? := mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/core/
else
MACHINE ? ? ? ? := $(MTK_PATH_PLATFORM)/core/
machdirs ? ? ? ?:= $(MTK_PATH_PLATFORM)/core/
endif
platdirs ? ? ? ?:=
ifeq ($(strip $(KBUILD_OUTPUT_SUPPORT)),yes)
drivers-y ? ? ? += mediatek/source/kernel/
drivers-y ? ? ? += mediatek/custom/out/$(FULL_PROJECT)/kernel/
drivers-y ? ? ? += mediatek/platform/$(call lc,$(MTK_PLATFORM))/kernel/drivers/
else
drivers-y ? ? ? += $(MTK_PATH_PLATFORM)/drivers/
drivers-y ? ? ? += $(MTK_PATH_SOURCE)/
drivers-y ? ? ? += $(MTK_PATH_CUSTOM)/
endif
4.1.2 PLL與Clock
mt6577_clock_manager.c中“static void mt6577_clock_init(void)”“static void mt6577_pll_init(void)”
mt6577的clock定義如下
enum mt65xx_clock_id {
? ? /* PERI_GLOBALCON_PDN0 */
? ? MT65XX_PDN_PERI_NFI ? ? ? ? ? ? ? ? = 0,
? ? …
? ??
? ? /* PERI_GLOBALCON_PDN1 */
? ? MT65XX_PDN_PERI_SEJ ? ? ? ? ? ? ? ? = 32,
? ? …
? ? /* MMSYS1 Clock Gating #0 */
MT65XX_PDN_MM_VBUF ? ? ? ? ? ? ? ? ?= 64,
…
? ? /* MMSYS1 Clock Gating #1 */
? ? MT65XX_PDN_MM_VRZ1 ? ? ? ? ? ? ? ? ?= 96,
? ? …
? ? /*MMSYS1 Clock Gating #2 */
? ? MT65XX_PDN_MM_SCAM ? ? ? ? ? ? ? ? ?= 128,
? ? …
? ??
MT65XX_CLOCK_AUDIO_PDN, /* 32*6 = 192*/
? ? MT65XX_AUDIO_PDN_END ? ? ? ? ? ? ? ?= MT65XX_PDN_AUDIO_I2S,
? ? MT65XX_CLOCK_COUNT,
};
按照32,分組,enbale某個clock時,首先找到分組,然后找到組內偏移,針對某個組進行操作。中間根據clock組編號區分出 AP AP1 MM1 MM2等不同始終組,進行特殊操作。
不同的驅動在自己初始化函數里enable自己需要clock id—實際上enable對應的clock組。
int enable_clock(enum mt65xx_clock_id id, char *mod_name)
{
? ? unsigned long flags;
? ? int ret = 0;
? ? int category = id / CLK_REG_WIDTH;
int offset = id % CLK_REG_WIDTH;
if (CATEGORY_AP1(category)) {
…
}
…
if (CATEGORY_MM(category)) {
…
}
if (CATEGORY_AUD(category)) {
…
}
ret = enable_clock_internal(category, mask);
5 CpuFreq
5.1 初始化
在“static int mtk_cpufreq_init(…)”里根據處理器的版本選擇調頻表:
static struct mtk_cpu_freq_info mt6575_freqs_e1[] = {
? ? OP(DVFS_F2_MT6575_E1),
? ? OP(DVFS_F1_MT6575_E1),
};
/***************************
* MT6575 E2 DVFS Table
****************************/
static struct mtk_cpu_freq_info mt6575_freqs_e2[] = {
? ? OP(DVFS_F4_MT6575_E2),
? ? …
};
/***************************
* MT6577 E1 DVFS Table
****************************/
static struct mtk_cpu_freq_info mt6577_freqs_e1[] = {
? ? OP(DVFS_F6_MT6577_E1),
? ? …
? ? OP(DVFS_F1_MT6577_E1),
};
/***************************
* MT6577 E1 TM DVFS Table
****************************/
static struct mtk_cpu_freq_info mt6577_freqs_e1_tm[] = {
? ? OP(DVFS_F6_MT6577_E1_TM),
? ? …
? ? OP(DVFS_F1_MT6577_E1_TM),
};
調頻操作在“static int mtk_cpufreq_target()”里完成。
5.2 基本數據結構
調頻例程
static struct cpufreq_driver mtk_cpufreq_driver = {
? ? .verify = mtk_cpufreq_verify,
? ? .target = mtk_cpufreq_target,
? ? .init ? = mtk_cpufreq_init,
? ? .get ? ?= mtk_cpufreq_get,
? ? .name ? = "mtk-cpufreq",
};
5.7 調頻
/**********************************
* cpufreq target callback function
***********************************/
/*************************************************
* [note]
* 1. handle frequency change request
* 2. call mtk_cpufreq_set to set target frequency
**************************************************/
static int mtk_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation)
{
? ? …
? ? /******************************
? ? * look up the target frequency
? ? *******************************/
? ? if (cpufreq_frequency_table_target(policy, mtk_cpu_freqs_table, target_freq, relation, &idx))
? ? ? ? return -EINVAL;
? ?
//idx是目標調頻點索引值
? ? if (get_chip_ver() >= CHIP_6577_E1)
? ? {…
? ? }
? ? else if (get_chip_ver() >= CHIP_6575_E2)
? ? {
? ? ? ? next = &mt6575_freqs_e2[idx];
? ? }
? ? …
?
// next指向目標調頻點
// freqs.old是當前頻點,freqs.new是目標頻點
? ? freqs.old = policy->cur;
? ? freqs.new = next->cpufreq_mhz;
? ? freqs.cpu = policy->cpu;
? ??
? ? #ifndef MTK_DVFS_RANDOM_TEST
? ? if (mtk_cpufreq_keep_max_freq(freqs.old, freqs.new))
? ? {
? ? ? ? if ((DRV_Reg32(HW_RESV) & (0x1 << 23)) && ((DRV_Reg32(HW_RESV) & (0x1 << 20)) == 0))
? ? ? ? ? ? freqs.new = DVFS_F1_TM;
? ? ? ? else
? ? ? ? ? ? freqs.new = DVFS_F1;
? ? }
? ? if (freqs.new > g_limited_freq)
? ? {
? ? ? ? dprintk("CPU frequency has been limited to %d Mhz, request %d Mhz will be limited\n", g_limited_freq / 1000, freqs.new / 1000);
? ? ? ? freqs.new = g_limited_freq;
? ? }
? ? if (freqs.new < g_limited_min_freq)
? ? {
? ? ? ? dprintk("cannot switch CPU frequency to %d Mhz due to voltage limitation\n", g_limited_min_freq / 1000);
? ? ? ? freqs.new = g_limited_min_freq;
? ? }
? ? #endif
? ? /************************************************
? ? * target frequency == existing frequency, skip it
? ? *************************************************/
? ? if (freqs.old == freqs.new)
? ? {
? ? ? ? dprintk("CPU frequency from %d MHz to %d MHz (skipped) due to same frequency\n", freqs.old / 1000, freqs.new / 1000);
? ? ? ? return 0;
? ? }
/*調頻前對所有ONLINE CPU發出通知*/
? ? for_each_online_cpu(cpu)
? ? {
? ? ? ? freqs.cpu = cpu;
? ? ? ? cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
? ? }
? ? spin_lock_irqsave(&mtk_cpufreq_lock, flags);
? ? /*********************************************
? ? * update current frequency due to last change
? ? **********************************************/
? ? freqs.old = g_cur_freq;
? ? /******************************
? ? * set to the target freeuency
*******************************/
//真正的調頻操作
? ? mtk_cpufreq_set(freqs.old, freqs.new);
? ? spin_unlock_irqrestore(&mtk_cpufreq_lock, flags);
/*調頻后對所有ONLINE CPU發出通知*/
? ? for_each_online_cpu(cpu)
? ? {
? ? ? ? freqs.cpu = cpu;
? ? ? ? cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
? ? }
? ? return 0;
}
/*****************************************
* frequency ramp up and ramp down handler
******************************************/
/***********************************************************
* [note]
* 1. frequency ramp up need to wait voltage settle
* 2. frequency ramp down do not need to wait voltage settle
************************************************************/
static void mtk_cpufreq_set(unsigned int freq_old, unsigned int freq_new)
{
? ? if (freq_new == DVFS_F1 || freq_new == DVFS_F1_TM) /* set ARMPLL divider to 1/1 */
? ? {
? ? ? ? …
? ? }
? ? else if (freq_new == DVFS_F2 || freq_new == DVFS_F2_TM) /* set ARMPLL divider to 5/6 */
? ? {
? ? ? ? if (freq_new > freq_old)
? ? ? ? { ? ?//升頻,先調壓再調頻
//調壓
? ? ? ? ? ? #ifdef MTK_BUCK_ADJUST
? ? ? ? ? ? DRV_WriteReg32(SC_AP_DVFS_CON, ((DRV_Reg32(SC_AP_DVFS_CON) & 0xFFFFFFFC) | 0x03));
? ? ? ? ? ? mb();
? ? ? ? ? ? udelay(PMIC_SETTLE_TIME);
? ? ? ? ? ? #endif
? ? ? ? ? ?
? ? ? ? ? ??
? ? ? ? ? ? g_cur_freq = freq_new;
//調頻
? ? ? ? ? ? DRV_WriteReg32(TOP_CKDIV1, 0x19);
? ? ? ? }
? ? ? ? else
? ? ? ? { ? //降頻,先調頻再調壓
? ? ? ? ? ? //調頻
? ? ? ? ? ? g_cur_freq = freq_new;
? ? ? ? ? ? DRV_WriteReg32(TOP_CKDIV1, 0x19);
? ? ? ? ? ? mb();
? ? ? ? ? ? ?
//調壓
? ? ? ? ? ? #ifdef MTK_BUCK_ADJUST
? ? ? ? ? ? DRV_WriteReg32(SC_AP_DVFS_CON, ((DRV_Reg32(SC_AP_DVFS_CON) & 0xFFFFFFFC) | 0x03));
? ? ? ? ? ? #endif
? ? ? ? }
? ? }
? ? else if (freq_new == DVFS_F3 || freq_new == DVFS_F3_TM) /* set ARMPLL divider to 3/4 */
? ? {
? ? ??
? ? }
? ? else if (freq_new == DVFS_F4 || freq_new == DVFS_F4_TM) /* set ARMPLL divider to 2/3 */
? ? {
? ? }
? ? else if (freq_new == DVFS_F5 || freq_new == DVFS_F5_TM) /* set ARMPLL divider to 1/2 */
? ? {
? ? }
? ? else if (freq_new == DVFS_F6 || freq_new == DVFS_F6_TM) /* set ARMPLL divider to 1/4 */
? ? {
? ? }
? ? else if (freq_new == DVFS_F7 || freq_new == DVFS_F7_TM) /* set ARMPLL divider to 1/6 */
? ? {
? ? }
? ?
}
6 IRQ
6.1 中斷體系
根據arm gic規范,
0-15 SGI
16-31 PPP
32以上 SPI
6.3 外部中斷
typedef struct?
{
? ? void (*eint_func[EINT_MAX_CHANNEL])(void);
? ? unsigned int eint_auto_umask[EINT_MAX_CHANNEL];
} eint_func;
通過“void mt65xx_eint_registration(…)”注冊自己的中斷函數。
比如“alps\mediatek\custom\common\kernel\touchpanel\ft5206\ft5206_driver.c”通過該函數注冊自己的中斷處理函數:
? ? mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_POLARITY_HIGH, tpd_eint_interrupt_handler, 1);
外部中斷的入口是“static irqreturn_t mt65xx_eint_isr(int irq, void *dev_id)”,該函數會檢查“eint_func”數組里的處理函數。而整個外部中斷入口是由EINT_IRQ中斷觸發。在“alps\mediatek\platform\mt6577\kernel\core\mt6577_eint.c”將EINT_IRQ中斷掛入6577的中斷體系。
if (request_irq(EINT_IRQ, mt65xx_eint_isr, IRQF_TRIGGER_HIGH, "EINT", NULL)) {
? ? ? ? printk(KERN_ERR "EINT IRQ LINE NOT AVAILABLE!!\n");
}
6.4 wakeup
static u16 sc_wake_irq[NUM_WAKE_SRC] = {
[2] = MT6577_KP_IRQ_ID,
[3] = MT6577_MSDC1_IRQ_ID,
[5] = MT6577_EINT_IRQ_ID,
[6] = MT6577_RTC_IRQ_ID,
[7] = MT6577_AP_CCIF_IRQ_ID,
[8] = MT6577_ACCDET_IRQ_ID,
};
15 Driver
15.1 LCM
修改lps/mediatek/config/common/ProjectConfig.mk”里的“CUSTOM_KERNEL_LCM”和 “CUSTOM_UBOOT_LCM”選項將影響到文件“alps/mediatek/config/out/mt6577/ProjectConfig.mk”
將上述兩項CUSTOM_KERNEL_LCM=hx8369_6575 ?CUSTOM_UBOOT_LCM=hx8369_6575
導致
alps/mediatek/custom/common/kernel/lcm/hx8369_6575/hx8369_6575.c拷到如下兩個目錄
alps/mediatek/custom/out/mt6577/kernel/lcm
alps/mediatek/custom/out/mt6577/uboot/lcm
mediatek\source\kernel\drivers\video
static const DISP_DRIVER DSI_DISP_DRV
const LCM_DRIVER *disp_drv_get_lcm_driver(const char *lcm_name)
15.2 BL
mediatek\source\kernel\drivers\led\leds.c
{
if(strcmp(g_leds_data[i]->cdev.name,"lcd-backlight") == 0)
{
rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_duty);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_div);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
? ? ? ? ? ??
? ? ? ? ? ? rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_frequency);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
? ? ? ? ? ??
? ?rc = device_create_file(g_leds_data[i]->cdev.dev, &dev_attr_pwm_register);
? ? ? ? ? ? if(rc)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? LEDS_DEBUG("[LED]device_create_file duty fail!\n");
? ? ? ? ? ? }
bl_setting = &g_leds_data[i]->cust;
}
}
static DEVICE_ATTR(duty, 0664, show_duty, store_duty);
g_leds_data
[ ? 40.450409] (0)[313:ScreenOffThread][LED]Set Backlight directly 102 at time 4294941336
[ ? 40.451398] (0)[313:ScreenOffThread]mt65xx_leds_set_cust: set brightness, name:lcd-backlight, mode:3, level:102
[ ? 40.452744] (0)[313:ScreenOffThread]brightness_set_pmic1[LED]PMIC#3:102
[ ? 40.454159] (0)[313:ScreenOffThread]brightness_set_pmic3 2
brightness_set_pmic
mt65xx_leds_brightness_set
led_brightness_set
15.3 TP
alps\mediatek\custom\common\kernel\touchpanel\ft5206
alps\mediatek\custom\common\kernel\touchpanel\src
15.5 Musb
15.5.1 配置
盡管在
mediatek/config/mt6577/autoconfig/kconfig/platform
CONFIG_USB_MTK_HDRC_HCD is not set
CONFIG_USB_MTK_OTG is not set
但是在
mediatek/config/mt6577/autoconfig/kconfig/project
CONFIG_USB_MTK_HDRC_HCD=y
CONFIG_USB_MTK_OTG=y
15.5.2 Platform device & driver
mediatek\platform\mt6577\kernel\core
struct platform_device mt_device_usb = {
.name ?= "mt_usb",
.id ?= -1,
.dev = { ? ? ? ? ? ? ? ?
//.platform_data ? ? ? ? ?= &usb_data_mt65xx, ? ??
.dma_mask ? ? ? ? ? ? ? = &usb_dmamask,
.coherent_dma_mask ? ? ?= DMA_BIT_MASK(32),?
//.release=musbfsh_hcd_release, ? ?
},
};
__init int mt6577_board_init(void)
{
…
#if defined(CONFIG_USB_MTK_HDRC)
printk("mt_device_usb register\n");
retval = platform_device_register(&mt_device_usb);
if (retval != 0){
printk("mt_device_usb register fail\n");
? ? ? ? return retval;
}
#endif
…
}
mediatek\source\kernel\drivers\usb20
static struct platform_driver musb_driver = {
.driver = {
.name = (char *)musb_driver_name,
.owner = THIS_MODULE,
},
.remove = __exit_p(musb_remove),
.shutdown = musb_shutdown,
.probe = musb_probe,
};
data_array[0]=0x00103902;
? ? ? ? data_array[1]=0x032000B2;
? ? ? ? data_array[2]=0xFF007003;
? ? ? ? data_array[3]=0x00000000;
? ? ? ? data_array[4]=0x01000303;
? ? ? ? dsi_set_cmdq(&data_array, 5, 1);
? data_array[0] 為packet head ?定義為:第一個字節為 WC1,第二個字節WC0,第三個字節DT (命令類型)第四個字節為控制類型。
? data_array[1],data_array[2],data_array[3],data_array[4],為初始化的相應數據。
15.6 GPIO
GPIO初始化在uboot里完成
GPIO在內核的定義:
cust_gpio_usage.h
GPIO在內核的設置
mt_set_gpio_mode
15.7 IIC
15.7.1 ?adapter device
alps\mediatek\platform\mt6577\kernel\core\Mt6577_devs.c
static struct platform_device mt_device_i2c[] = {
? ? {
? ? ? ? .name ? ? ? ? ? = "mt-i2c",
? ? ? ? .id ? ? ? ? ? ? = 0,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt_resource_i2c1),
? ? ? ? .resource ? ? ? = mt_resource_i2c1,
? ? },
…
? ? {
? ? ? ? .name ? ? ? ? ? = "mt-i2c",
? ? ? ? .id ? ? ? ? ? ? = 2,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt_resource_i2c3),
? ? ? ? .resource ? ? ? = mt_resource_i2c3,
? ? },
};
15.7.2 adapter driver
alps\mediatek\platform\mt6577\kernel\drivers\i2c\I2c.c
static struct platform_driver mt_i2c_driver = {
? ? .probe = mt_i2c_probe,
? ? .remove = mt_i2c_remove,
#ifdef CONFIG_PM
? ? .suspend = mt_i2c_suspend,
? ? .resume = mt_i2c_resume,
#endif
? ? .driver ?= {
? ? ? ? .name ?= DRV_NAME,
? ? ? ? .owner = THIS_MODULE,
? ? },
};
15.7.3 匹配IIC通道
i2c_register_board_info
15.8 PMIC MT6329
alps\mediatek\platform\mt6577\kernel\drivers\power\pmic_mt6329.c
i2c_register_board_info 指出mt6329使用2通道
15.9 emmc & sd
C:\senix\rd\mtk\6577\source-code\src\alps\mediatek\platform\mt6577\kernel\core\ mt6577_devs.c
static struct platform_device mt6577_device_sd[] =
{
#if defined(CFG_DEV_MSDC0)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 0,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd0),
? ? ? ? .resource ? ? ? = mt6577_resource_sd0,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc0_hw,
? ? ? ? },
? ? },
#endif
#if defined(CFG_DEV_MSDC1)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 1,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd1),
? ? ? ? .resource ? ? ? = mt6577_resource_sd1,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc1_hw,
? ? ? ? },
? ? },
#endif
#if defined(CFG_DEV_MSDC2)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 2,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd2),
? ? ? ? .resource ? ? ? = mt6577_resource_sd2,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc2_hw,
? ? ? ? },
? ? },
#endif
#if defined(CFG_DEV_MSDC3)
? ? {
? ? ? ? .name ? ? ? ? ? = "mtk-sd",
? ? ? ? .id ? ? ? ? ? ? = 3,
? ? ? ? .num_resources ?= ARRAY_SIZE(mt6577_resource_sd3),
? ? ? ? .resource ? ? ? = mt6577_resource_sd3,
? ? ? ? .dev = {
? ? ? ? ? ? .platform_data = &msdc3_hw,
? ? ? ? },
? ? },
#endif
};
驅動
c:\senix\rd\mtk\6577\source-code\src\alps\mediatek\platform\mt6577\kernel\drivers\mmc-host\sd.c
EMMC數據線定義
struct msdc_hw msdc0_hw = {
? ?.clk_src ? ? ? ?= 1,
? ?.cmd_edge ? ? ? = MSDC_SMPL_FALLING,
? ?.data_edge ? ? ?= MSDC_SMPL_FALLING,
? ?…
? ?.data_pins ? ? ?= 8,
? ?.data_offset ? ?= 0,
#ifdef MTK_EMMC_SUPPORT
? ?.flags ? ? ? ? ?= MSDC_SYS_SUSPEND | MSDC_HIGHSPEED,
#else
? ?.flags ? ? ? ? ?= MSDC_SDCARD_FLAG,
#endif
};
static struct mmc_host_ops mt_msdc_ops = {
? ? .request ? ? ? ? = msdc_ops_request,
? ? .set_ios ? ? ? ? = msdc_ops_set_ios,
? ? .get_ro ? ? ? ? ?= msdc_ops_get_ro,
? ? .get_cd ? ? ? ? ?= msdc_ops_get_cd,
? ? .enable_sdio_irq = msdc_ops_enable_sdio_irq,
? ? .start_signal_voltage_switch = msdc_ops_switch_volt,
};
Host
Mmc card device
Mmc card driver
mmc_rescan 掃描mmc 家里mmc設備
mmc_init_card
mmc_blk_probe
?add_disk
總結
以上是生活随笔為你收集整理的mt6577驱动开发 笔记版 转载请注明出处---crosskernel@gmail.com的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: selenium小白学习笔记(6) -
- 下一篇: 他 1 个月写了个操作系统,退休后去做飞
