Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at for-next 238 lines 5.6 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2// 3// rt-sdw-common.c 4// 5// Copyright(c) 2024 Realtek Semiconductor Corp. 6// 7 8/* 9 * This file defines common functions used with Realtek soundwire codecs. 10 */ 11 12#include <linux/module.h> 13#include <linux/regmap.h> 14#include <linux/bitops.h> 15#include <linux/soundwire/sdw_registers.h> 16#include <sound/jack.h> 17 18#include "rt-sdw-common.h" 19 20/** 21 * rt_sdca_index_write - Write a value to Realtek defined register. 22 * 23 * @map: map for setting. 24 * @nid: Realtek-defined ID. 25 * @reg: register. 26 * @value: value. 27 * 28 * A value of zero will be returned on success, a negative errno will 29 * be returned in error cases. 30 */ 31int rt_sdca_index_write(struct regmap *map, unsigned int nid, 32 unsigned int reg, unsigned int value) 33{ 34 unsigned int addr = (nid << 20) | reg; 35 int ret; 36 37 ret = regmap_write(map, addr, value); 38 if (ret < 0) 39 pr_err("Failed to set value: %06x <= %04x ret=%d\n", 40 addr, value, ret); 41 42 return ret; 43} 44EXPORT_SYMBOL_GPL(rt_sdca_index_write); 45 46/** 47 * rt_sdca_index_read - Read value from Realtek defined register. 48 * 49 * @map: map for setting. 50 * @nid: Realtek-defined ID. 51 * @reg: register. 52 * @value: value. 53 * 54 * A value of zero will be returned on success, a negative errno will 55 * be returned in error cases. 56 */ 57int rt_sdca_index_read(struct regmap *map, unsigned int nid, 58 unsigned int reg, unsigned int *value) 59{ 60 unsigned int addr = (nid << 20) | reg; 61 int ret; 62 63 ret = regmap_read(map, addr, value); 64 if (ret < 0) 65 pr_err("Failed to get value: %06x => %04x ret=%d\n", 66 addr, *value, ret); 67 68 return ret; 69} 70EXPORT_SYMBOL_GPL(rt_sdca_index_read); 71 72/** 73 * rt_sdca_index_update_bits - Update value on Realtek defined register. 74 * 75 * @map: map for setting. 76 * @nid: Realtek-defined ID. 77 * @reg: register. 78 * @mask: Bitmask to change 79 * @val: New value for bitmask 80 * 81 * A value of zero will be returned on success, a negative errno will 82 * be returned in error cases. 83 */ 84 85int rt_sdca_index_update_bits(struct regmap *map, 86 unsigned int nid, unsigned int reg, unsigned int mask, unsigned int val) 87{ 88 unsigned int tmp; 89 int ret; 90 91 ret = rt_sdca_index_read(map, nid, reg, &tmp); 92 if (ret < 0) 93 return ret; 94 95 set_mask_bits(&tmp, mask, val); 96 return rt_sdca_index_write(map, nid, reg, tmp); 97} 98EXPORT_SYMBOL_GPL(rt_sdca_index_update_bits); 99 100/** 101 * rt_sdca_btn_type - Decision of button type. 102 * 103 * @buffer: UMP message buffer. 104 * 105 * A button type will be returned regarding to buffer, 106 * it returns zero if buffer cannot be recognized. 107 */ 108int rt_sdca_btn_type(unsigned char *buffer) 109{ 110 u8 btn_type = 0; 111 int ret = 0; 112 113 btn_type |= buffer[0] & 0xf; 114 btn_type |= (buffer[0] >> 4) & 0xf; 115 btn_type |= buffer[1] & 0xf; 116 btn_type |= (buffer[1] >> 4) & 0xf; 117 118 if (btn_type & BIT(0)) 119 ret |= SND_JACK_BTN_2; 120 if (btn_type & BIT(1)) 121 ret |= SND_JACK_BTN_3; 122 if (btn_type & BIT(2)) 123 ret |= SND_JACK_BTN_0; 124 if (btn_type & BIT(3)) 125 ret |= SND_JACK_BTN_1; 126 127 return ret; 128} 129EXPORT_SYMBOL_GPL(rt_sdca_btn_type); 130 131/** 132 * rt_sdca_headset_detect - Headset jack type detection. 133 * 134 * @map: map for setting. 135 * @entity_id: SDCA entity ID. 136 * 137 * A headset jack type will be returned, a negative errno will 138 * be returned in error cases. 139 */ 140int rt_sdca_headset_detect(struct regmap *map, unsigned int entity_id) 141{ 142 unsigned int det_mode, jack_type; 143 int ret; 144 145 /* get detected_mode */ 146 ret = regmap_read(map, SDW_SDCA_CTL(SDCA_NUM_JACK_CODEC, entity_id, 147 RT_SDCA_CTL_DETECTED_MODE, 0), &det_mode); 148 149 if (ret < 0) 150 goto io_error; 151 152 switch (det_mode) { 153 case 0x03: 154 jack_type = SND_JACK_HEADPHONE; 155 break; 156 case 0x05: 157 jack_type = SND_JACK_HEADSET; 158 break; 159 default: 160 jack_type = 0; 161 break; 162 } 163 164 /* write selected_mode */ 165 if (det_mode) { 166 ret = regmap_write(map, SDW_SDCA_CTL(SDCA_NUM_JACK_CODEC, entity_id, 167 RT_SDCA_CTL_SELECTED_MODE, 0), det_mode); 168 if (ret < 0) 169 goto io_error; 170 } 171 172 return jack_type; 173 174io_error: 175 pr_err_ratelimited("IO error in %s, ret %d\n", __func__, ret); 176 return ret; 177} 178EXPORT_SYMBOL_GPL(rt_sdca_headset_detect); 179 180/** 181 * rt_sdca_button_detect - Read UMP message and decide button type. 182 * 183 * @map: map for setting. 184 * @entity_id: SDCA entity ID. 185 * @hid_buf_addr: HID buffer address. 186 * @hid_id: Report ID for HID. 187 * 188 * A button type will be returned regarding to buffer, 189 * it returns zero if buffer cannot be recognized. 190 */ 191int rt_sdca_button_detect(struct regmap *map, unsigned int entity_id, 192 unsigned int hid_buf_addr, unsigned int hid_id) 193{ 194 unsigned int btn_type = 0, offset, idx, val, owner; 195 unsigned char buf[3]; 196 int ret; 197 198 /* get current UMP message owner */ 199 ret = regmap_read(map, SDW_SDCA_CTL(SDCA_NUM_HID, entity_id, 200 RT_SDCA_CTL_HIDTX_CURRENT_OWNER, 0), &owner); 201 if (ret < 0) 202 return 0; 203 204 /* if owner is device then there is no button event from device */ 205 if (owner == 1) 206 return 0; 207 208 /* read UMP message offset */ 209 ret = regmap_read(map, SDW_SDCA_CTL(SDCA_NUM_HID, entity_id, 210 RT_SDCA_CTL_HIDTX_MESSAGE_OFFSET, 0), &offset); 211 if (ret < 0) 212 goto _end_btn_det_; 213 214 for (idx = 0; idx < sizeof(buf); idx++) { 215 ret = regmap_read(map, hid_buf_addr + offset + idx, &val); 216 if (ret < 0) 217 goto _end_btn_det_; 218 buf[idx] = val & 0xff; 219 } 220 /* Report ID for HID */ 221 if (buf[0] == hid_id) 222 btn_type = rt_sdca_btn_type(&buf[1]); 223 224_end_btn_det_: 225 /* Host is owner, so set back to device */ 226 if (owner == 0) 227 /* set owner to device */ 228 regmap_write(map, 229 SDW_SDCA_CTL(SDCA_NUM_HID, entity_id, 230 RT_SDCA_CTL_HIDTX_CURRENT_OWNER, 0), 0x01); 231 232 return btn_type; 233} 234EXPORT_SYMBOL_GPL(rt_sdca_button_detect); 235 236MODULE_DESCRIPTION("Realtek soundwire common functions"); 237MODULE_AUTHOR("jack yu <jack.yu@realtek.com>"); 238MODULE_LICENSE("GPL");