diff --git a/drivers/dai/dai_handlers.c b/drivers/dai/dai_handlers.c index 28283e25a66b..0f4388c94f57 100644 --- a/drivers/dai/dai_handlers.c +++ b/drivers/dai/dai_handlers.c @@ -36,15 +36,21 @@ static inline int z_vrfy_dai_config_set(const struct device *dev, size_t size) { uint8_t bespoke_cfg_kernel[DAI_MAX_BESPOKE_CFG_SIZE]; + struct dai_config cfg_kernel; if (size > DAI_MAX_BESPOKE_CFG_SIZE) { return -EINVAL; } K_OOPS(K_SYSCALL_DRIVER_DAI(dev, config_set)); - K_OOPS(k_usermode_from_copy(bespoke_cfg_kernel, bespoke_cfg, size)); + K_OOPS(k_usermode_from_copy(&cfg_kernel, cfg, sizeof(cfg_kernel))); - return z_impl_dai_config_set(dev, cfg, bespoke_cfg_kernel, size); + if (bespoke_cfg) { + K_OOPS(k_usermode_from_copy(bespoke_cfg_kernel, bespoke_cfg, size)); + } + + return z_impl_dai_config_set(dev, &cfg_kernel, + bespoke_cfg ? bespoke_cfg_kernel : NULL, size); } #include @@ -133,7 +139,7 @@ static inline int z_vrfy_dai_config_update(const struct device *dev, { uint8_t bespoke_cfg_kernel[DAI_MAX_BESPOKE_CFG_SIZE]; - if (size > DAI_MAX_BESPOKE_CFG_SIZE) { + if (!bespoke_cfg || size > DAI_MAX_BESPOKE_CFG_SIZE) { return -EINVAL; } diff --git a/drivers/dai/intel/alh/alh.c b/drivers/dai/intel/alh/alh.c index 7d8dd0dd14c5..230da39a1ecf 100644 --- a/drivers/dai/intel/alh/alh.c +++ b/drivers/dai/intel/alh/alh.c @@ -158,6 +158,25 @@ static const struct dai_properties *dai_alh_get_properties(const struct device * return prop; } +static int dai_alh_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, + struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_alh_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + if (!kernel_prop) { + return -ENOENT; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static int dai_alh_probe(const struct device *dev) { k_spinlock_key_t key; @@ -201,6 +220,7 @@ static DEVICE_API(dai, dai_intel_alh_api_funcs) = { .config_get = dai_alh_config_get, .trigger = dai_alh_trigger, .get_properties = dai_alh_get_properties, + .get_properties_copy = dai_alh_get_properties_copy, }; #define DAI_INTEL_ALH_DEVICE_INIT(n) \ diff --git a/drivers/dai/intel/dmic/dmic.c b/drivers/dai/intel/dmic/dmic.c index a55a74728ce0..79b71e5d66f8 100644 --- a/drivers/dai/intel/dmic/dmic.c +++ b/drivers/dai/intel/dmic/dmic.c @@ -686,6 +686,25 @@ const struct dai_properties *dai_dmic_get_properties(const struct device *dev, return prop; } +static int dai_dmic_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, + struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_dmic_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + if (!kernel_prop) { + return -ENOENT; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static int dai_dmic_trigger(const struct device *dev, enum dai_dir dir, enum dai_trigger_cmd cmd) { @@ -857,6 +876,7 @@ DEVICE_API(dai, dai_dmic_ops) = { .config_set = dai_dmic_set_config, .config_get = dai_dmic_get_config, .get_properties = dai_dmic_get_properties, + .get_properties_copy = dai_dmic_get_properties_copy, .trigger = dai_dmic_trigger, .ts_config = dai_dmic_timestamp_config, .ts_start = dai_timestamp_dmic_start, diff --git a/drivers/dai/intel/hda/hda.c b/drivers/dai/intel/hda/hda.c index c901b20600b0..535fd625d970 100644 --- a/drivers/dai/intel/hda/hda.c +++ b/drivers/dai/intel/hda/hda.c @@ -92,6 +92,25 @@ static const struct dai_properties *dai_hda_get_properties(const struct device * return prop; } +static int dai_hda_get_properties_copy(const struct device *dev, + enum dai_dir dir, int stream_id, + struct dai_properties *prop) +{ + const struct dai_properties *kernel_prop = dai_hda_get_properties(dev, dir, stream_id); + + if (!prop) { + return -EINVAL; + } + + if (!kernel_prop) { + return -ENOENT; + } + + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); + + return 0; +} + static int dai_hda_probe(const struct device *dev) { LOG_DBG("%s", __func__); @@ -139,6 +158,7 @@ static DEVICE_API(dai, dai_intel_hda_api_funcs) = { .config_get = dai_hda_config_get, .trigger = dai_hda_trigger, .get_properties = dai_hda_get_properties, + .get_properties_copy = dai_hda_get_properties_copy, }; #define DAI_INTEL_HDA_DEVICE_INIT(n) \ diff --git a/drivers/dai/intel/ssp/ssp.c b/drivers/dai/intel/ssp/ssp.c index 653f1d481687..a2395a611ac0 100644 --- a/drivers/dai/intel/ssp/ssp.c +++ b/drivers/dai/intel/ssp/ssp.c @@ -2549,7 +2549,8 @@ static const struct dai_properties *dai_ssp_get_properties(const struct device * } static int dai_ssp_get_properties_copy(const struct device *dev, - enum dai_dir dir, int stream_id, struct dai_properties *prop) + enum dai_dir dir, int stream_id, + struct dai_properties *prop) { const struct dai_properties *kernel_prop = dai_ssp_get_properties(dev, dir, stream_id); @@ -2557,6 +2558,10 @@ static int dai_ssp_get_properties_copy(const struct device *dev, return -EINVAL; } + if (!kernel_prop) { + return -ENOENT; + } + memcpy(prop, kernel_prop, sizeof(*kernel_prop)); return 0; diff --git a/include/zephyr/drivers/dai.h b/include/zephyr/drivers/dai.h index 606a2f325668..cf37982725fa 100644 --- a/include/zephyr/drivers/dai.h +++ b/include/zephyr/drivers/dai.h @@ -463,12 +463,17 @@ static inline const struct dai_properties *dai_get_properties(const struct devic /** * @brief Fetch properties of a DAI driver * + * Optional method. + * * @param dev Pointer to the device structure for the driver instance * @param dir Stream direction: RX or TX as defined by DAI_DIR_* * @param stream_id Stream id: some drivers may have stream specific * properties, this id specifies the stream. * @param dst address where to write properties to - * @retval Zero on success + * @retval 0 if success + * @retval -EINVAL if arguments are incorrect + * @retval -ENOENT if there are no properties for the device + * @retval -ENOSYS if method not implemented by the driver */ __syscall int dai_get_properties_copy(const struct device *dev, enum dai_dir dir, @@ -482,6 +487,10 @@ static inline int z_impl_dai_get_properties_copy(const struct device *dev, { const struct dai_driver_api *api = (const struct dai_driver_api *)dev->api; + if (!api->get_properties_copy) { + return -ENOSYS; + } + return api->get_properties_copy(dev, dir, stream_id, dst); }