mirror of
https://github.com/Rockbox/rockbox.git
synced 2026-10-10 08:03:04 -04:00
YP-CP3: WM8750 audio
The YP-CP3 uses Wolfson WM8750. Headphones are wired on OUT2 and a headphone amplifier enabled by GPIO F2, active high - all RE from the original firmware. The original firmware runs the codec as I2S master in its 12 MHz "USB mode", fed a fixed 12 MHz MCLK, which puts 44.1 kHz at 44.118. Rockbox instead makes the rk27xx the master and clocks the codec from the codec PLL at exactly 256 fs (CODEC_SLAVE, as every other rk27xx target with an external codec), so the codec's CLOCKING register is its normal-mode 256 fs setting at every rate. 96 kHz is left out: the WM8750 cannot take it at 256 fs. - config: HAVE_WM8750, CODEC_SLAVE, rates 8-48 kHz; the WM8750 has hardware tone controls, so HAVE_SW_TONE_CONTROLS goes - ypcp3/wmcodec-ypcp3.c: register writes over the rk27xx I2C driver - wm8751.c: on the YP-CP3, power on and drive OUT2 instead of OUT1, set the volume there, and switch the amplifier with the outputs - english.lang: the YP-CP3 gets the bass/treble cutoff settings the WM8750 brings Tested on a YP-CP3: playback at 44.1 and 48 kHz on headphones, pitch and volume correct. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Change-Id: I870038fb6a21a9c26b025e3df7c220fd925f49f6
This commit is contained in:
parent
f7655e226c
commit
a35f344eef
5 changed files with 75 additions and 9 deletions
|
|
@ -9284,15 +9284,15 @@
|
|||
user: core
|
||||
<source>
|
||||
*: none
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100: "Bass Cutoff"
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100,samsungypcp3: "Bass Cutoff"
|
||||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100: "Bass Cutoff"
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100,samsungypcp3: "Bass Cutoff"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100: "Bass Cutoff"
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100,samsungypcp3: "Bass Cutoff"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
@ -9301,15 +9301,15 @@
|
|||
user: core
|
||||
<source>
|
||||
*: none
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100: "Treble Cutoff"
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100,samsungypcp3: "Treble Cutoff"
|
||||
</source>
|
||||
<dest>
|
||||
*: none
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100: "Treble Cutoff"
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100,samsungypcp3: "Treble Cutoff"
|
||||
</dest>
|
||||
<voice>
|
||||
*: none
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100: "Treble Cutoff"
|
||||
gigabeatfx,ipod6g,ipodnano3g,ipodnano4g,ipodvideo,mpiohd200,mpiohd300,mrobe100,samsungypcp3: "Treble Cutoff"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
|
|
|
|||
|
|
@ -1736,6 +1736,9 @@ target/arm/rk27xx/ypcp3/button-ypcp3.c
|
|||
target/arm/rk27xx/ypcp3/powermgmt-ypcp3.c
|
||||
target/arm/rk27xx/ypcp3/power-ypcp3.c
|
||||
target/arm/rk27xx/ypcp3/lcd-ypcp3.c
|
||||
#ifndef BOOTLOADER
|
||||
target/arm/rk27xx/ypcp3/wmcodec-ypcp3.c
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if CONFIG_CPU == JZ4732
|
||||
|
|
|
|||
|
|
@ -187,6 +187,10 @@ void audiohw_preinit(void)
|
|||
and_l(~(1<<5), &GPIO1_OUT);
|
||||
or_l((1<<5), &GPIO1_ENABLE);
|
||||
or_l((1<<5), &GPIO1_FUNCTION);
|
||||
#elif defined(SAMSUNG_YPCP3)
|
||||
/* headphone amplifier enable, GPIO F2 active high: off for now */
|
||||
GPIO_PFDR &= ~(1<<2);
|
||||
GPIO_PFCON |= (1<<2);
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
|
@ -233,6 +237,9 @@ void audiohw_postinit(void)
|
|||
/* headphones + line-out */
|
||||
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1 |
|
||||
PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2);
|
||||
#elif defined(SAMSUNG_YPCP3)
|
||||
/* headphones, on OUT2 */
|
||||
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT2 | PWRMGMT2_ROUT2);
|
||||
#else
|
||||
/* headphones */
|
||||
wmcodec_set_bits(PWRMGMT2, PWRMGMT2_LOUT1 | PWRMGMT2_ROUT1);
|
||||
|
|
@ -286,6 +293,8 @@ void audiohw_postinit(void)
|
|||
or_l((1<<25), &GPIO1_OUT);
|
||||
#elif defined(MPIO_HD300)
|
||||
or_l((1<<5), &GPIO1_OUT);
|
||||
#elif defined(SAMSUNG_YPCP3)
|
||||
GPIO_PFDR |= (1<<2);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
@ -293,10 +302,18 @@ void audiohw_set_volume(int vol_l, int vol_r)
|
|||
{
|
||||
vol_l = vol_tenthdb2hw(vol_l);
|
||||
vol_r = vol_tenthdb2hw(vol_r);
|
||||
#if defined(SAMSUNG_YPCP3)
|
||||
/* headphones on OUT2 */
|
||||
wmcodec_set_masked(LOUT2, LOUT2_LOUT2VOL(vol_l),
|
||||
LOUT2_LOUT2VOL_MASK);
|
||||
wmcodec_set_masked(ROUT2, ROUT2_RO2VU | ROUT2_ROUT2VOL(vol_r),
|
||||
ROUT2_ROUT2VOL_MASK);
|
||||
#else
|
||||
wmcodec_set_masked(LOUT1, LOUT1_LOUT1VOL(vol_l),
|
||||
LOUT1_LOUT1VOL_MASK);
|
||||
wmcodec_set_masked(ROUT1, ROUT1_RO1VU | ROUT1_ROUT1VOL(vol_r),
|
||||
ROUT1_ROUT1VOL_MASK);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef AUDIOHW_HAVE_LINEOUT
|
||||
|
|
@ -353,6 +370,8 @@ void audiohw_close(void)
|
|||
and_l(~(1<<25), &GPIO1_OUT);
|
||||
#elif defined(MPIO_HD300)
|
||||
and_l(~(1<<5), &GPIO1_OUT);
|
||||
#elif defined(SAMSUNG_YPCP3)
|
||||
GPIO_PFDR &= ~(1<<2);
|
||||
#endif
|
||||
|
||||
/* 2. Disable all output buffers. */
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@
|
|||
#define CONFIG_STORAGE (STORAGE_SD | STORAGE_NAND)
|
||||
|
||||
#define CONFIG_NAND NAND_RK27XX
|
||||
#define HAVE_SW_TONE_CONTROLS
|
||||
|
||||
/* commented for now */
|
||||
/* #define HAVE_HOTSWAP */
|
||||
|
|
@ -93,8 +92,17 @@
|
|||
|
||||
#define CONFIG_LCD LCD_SPFD5420A
|
||||
|
||||
/* Define the type of audio codec */
|
||||
#define HAVE_RK27XX_CODEC
|
||||
/* Wolfson WM8750 on I2C, headphones on its OUT2. The codec is the I2S
|
||||
* slave: the rk27xx drives the bus and clocks the codec from its codec PLL
|
||||
* at 256 fs for every rate (pcm-rk27xx.c), so the codec's CLOCKING register
|
||||
* is its normal-mode 256 fs setting throughout. The original firmware runs
|
||||
* the codec as master off a fixed 12 MHz instead, in USB mode, which puts
|
||||
* 44.1 kHz at 44.118. */
|
||||
#define HAVE_WM8750
|
||||
#define CODEC_SLAVE
|
||||
#define CODEC_SRCTRL_11025HZ 0
|
||||
#define CODEC_SRCTRL_22050HZ 0
|
||||
#define CODEC_SRCTRL_44100HZ 0
|
||||
|
||||
/* Seiko S-35390A real-time clock on I2C, left in 12-hour mode by the
|
||||
* original firmware */
|
||||
|
|
|
|||
36
firmware/target/arm/rk27xx/ypcp3/wmcodec-ypcp3.c
Normal file
36
firmware/target/arm/rk27xx/ypcp3/wmcodec-ypcp3.c
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* Copyright (C) 2026 by Marcin Bukat
|
||||
*
|
||||
* 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
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include "system.h"
|
||||
#include "i2c-rk27xx.h"
|
||||
#include "wmcodec.h"
|
||||
|
||||
/* The WM8750's control interface in 2-wire mode, CSB low */
|
||||
#define WM8750_I2C_ADDR 0x34
|
||||
|
||||
/* A register write is two bytes: the 7-bit register number over bit 8 of
|
||||
* the value, then the value's low byte. */
|
||||
void wmcodec_write(int reg, int data)
|
||||
{
|
||||
unsigned char lo = data & 0xff;
|
||||
|
||||
i2c_write(WM8750_I2C_ADDR, (reg << 1) | ((data >> 8) & 1), 1, &lo);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue