Загрузка данных


static void wm8960_set_master_clock(const struct device *dev, uint32_t sysclk, uint32_t sampleRate, uint32_t bitWidth)
{
    uint32_t bitClockDivider = 0U, regDivider = 0U;
    uint8_t ret = 0;

    bitClockDivider = (sysclk * 2U) / (sampleRate * bitWidth * 2U);

    switch (bitClockDivider)
    {
        case 2:
            regDivider = 0U;
            break;
        case 3:
            regDivider = 1U;
            break;
        case 4:
            regDivider = 2U;
            break;
        case 6:
            regDivider = 3U;
            break;
        case 8:
            regDivider = 4U;
            break;
        case 11:
            regDivider = 5U;
            break;
        case 12:
            regDivider = 6U;
            break;
        case 16:
            regDivider = 7U;
            break;
        case 22:
            regDivider = 8U;
            break;
        case 24:
            regDivider = 9U;
            break;
        case 32:
            regDivider = 10U;
            break;
        case 44:
            regDivider = 11U;
            break;
        case 48:
            regDivider = 12U;
            break;

        default:
            LOG_ERR("Invalid bitClockDivider=%u\n",bitClockDivider);
            ret = 1;
            break;
    }
    if (ret == 0)
    {
        /* configure the master bit clock divider will be better */
        wm8960_update_reg(dev, WM8960_REG_CLOCK2, WM8960_CLOCK2_BCLK_DIV_MASK, (uint16_t)regDivider);
    }
}

static void wm8960_configure_output(const struct device *dev)
{
	wm8960_out_volume_config(dev, AUDIO_CHANNEL_ALL, WM8960_HEADPHONE_DEFAULT_VOLUME_VALUE);
	wm8960_out_mute_config(dev, AUDIO_CHANNEL_ALL, false);

	wm8960_apply_properties(dev);
}

static void wm8960_configure_input(const struct device *dev)
{
	wm8960_route_input(dev, AUDIO_CHANNEL_FRONT_LEFT, 0);
	wm8960_route_input(dev, AUDIO_CHANNEL_FRONT_RIGHT, 0);
	wm8960_in_volume_config(dev, AUDIO_CHANNEL_ALL, WM8960_LINEIN_DEFAULT_VOLUME_VALUE);
	wm8960_in_mute_config(dev, AUDIO_CHANNEL_ALL, false);
}

#if DEBUG_WM8960_REGISTER
static void WM8960_read_all_reg(const struct device *dev, uint16_t endAddress)
{
	uint16_t readValue = 0U, i = 0U;

	for (i = 0U; i < endAddress; i++) {
		wm8960_read_reg(dev, i, &readValue);
	}
}
#endif

static const struct audio_codec_api wm8960_driver_api = {.configure = wm8960_configure,
							 .start_output = wm8960_start_output,
							 .stop_output = wm8960_stop_output,
							 .set_property = wm8960_set_property,
							 .apply_properties = wm8960_apply_properties,
							 .route_input = wm8960_route_input,
							 .route_output = wm8960_route_output};

#define wm8960_INIT(n)                                                                             \
	static const struct wm8960_driver_config wm8960_device_config_##n = {                      \
		.i2c = I2C_DT_SPEC_INST_GET(n),                                                    \
		.clock_source = DT_INST_PROP_OR(n, clk_source, 0),                                 \
		.mclk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(n, mclk)),                   \
		.mclk_name = (clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_NAME(n, mclk, name)};  \
                                                                                                   \
	DEVICE_DT_INST_DEFINE(n, NULL, NULL, NULL, &wm8960_device_config_##n, POST_KERNEL,         \
			      CONFIG_AUDIO_CODEC_INIT_PRIORITY, &wm8960_driver_api);

DT_INST_FOREACH_STATUS_OKAY(wm8960_INIT)