Linux Audio

Check our new training course

Loading...
v5.4
  1/*
  2 * Copyright 2012-15 Advanced Micro Devices, Inc.
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 20 * OTHER DEALINGS IN THE SOFTWARE.
 21 *
 22 * Authors: AMD
 23 *
 24 */
 25
 26/*
 27 * Pre-requisites: headers required by header of this unit
 28 */
 29
 30#include <linux/slab.h>
 31
 32#include "dm_services.h"
 33
 34#include "include/gpio_interface.h"
 35#include "include/gpio_service_interface.h"
 36#include "hw_gpio.h"
 37#include "hw_translate.h"
 38#include "hw_factory.h"
 39#include "gpio_service.h"
 40
 41/*
 42 * Post-requisites: headers required by this unit
 43 */
 44
 45/*
 46 * This unit
 47 */
 48
 49/*
 50 * @brief
 51 * Public API
 52 */
 53
 54enum gpio_result dal_gpio_open(
 55	struct gpio *gpio,
 56	enum gpio_mode mode)
 57{
 58	return dal_gpio_open_ex(gpio, mode);
 59}
 60
 61enum gpio_result dal_gpio_open_ex(
 62	struct gpio *gpio,
 63	enum gpio_mode mode)
 64{
 65	if (gpio->pin) {
 66		ASSERT_CRITICAL(false);
 67		return GPIO_RESULT_ALREADY_OPENED;
 68	}
 69
 70	// No action if allocation failed during gpio construct
 71	if (!gpio->hw_container.ddc) {
 72		ASSERT_CRITICAL(false);
 73		return GPIO_RESULT_NON_SPECIFIC_ERROR;
 74	}
 75	gpio->mode = mode;
 76
 77	return dal_gpio_service_open(gpio);
 78}
 79
 80enum gpio_result dal_gpio_get_value(
 81	const struct gpio *gpio,
 82	uint32_t *value)
 83{
 84	if (!gpio->pin) {
 85		BREAK_TO_DEBUGGER();
 86		return GPIO_RESULT_NULL_HANDLE;
 87	}
 88
 89	return gpio->pin->funcs->get_value(gpio->pin, value);
 90}
 91
 92enum gpio_result dal_gpio_set_value(
 93	const struct gpio *gpio,
 94	uint32_t value)
 95{
 96	if (!gpio->pin) {
 97		BREAK_TO_DEBUGGER();
 98		return GPIO_RESULT_NULL_HANDLE;
 99	}
100
101	return gpio->pin->funcs->set_value(gpio->pin, value);
102}
103
104enum gpio_mode dal_gpio_get_mode(
105	const struct gpio *gpio)
106{
107	return gpio->mode;
108}
109
110enum gpio_result dal_gpio_lock_pin(
111	struct gpio *gpio)
112{
113	return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);
114}
115
116enum gpio_result dal_gpio_unlock_pin(
117	struct gpio *gpio)
118{
119	return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);
120}
121
122enum gpio_result dal_gpio_change_mode(
123	struct gpio *gpio,
124	enum gpio_mode mode)
125{
126	if (!gpio->pin) {
127		BREAK_TO_DEBUGGER();
128		return GPIO_RESULT_NULL_HANDLE;
129	}
130
131	return gpio->pin->funcs->change_mode(gpio->pin, mode);
132}
133
134enum gpio_id dal_gpio_get_id(
135	const struct gpio *gpio)
136{
137	return gpio->id;
138}
139
140uint32_t dal_gpio_get_enum(
141	const struct gpio *gpio)
142{
143	return gpio->en;
144}
145
146enum gpio_result dal_gpio_set_config(
147	struct gpio *gpio,
148	const struct gpio_config_data *config_data)
149{
150	if (!gpio->pin) {
151		BREAK_TO_DEBUGGER();
152		return GPIO_RESULT_NULL_HANDLE;
153	}
154
155	return gpio->pin->funcs->set_config(gpio->pin, config_data);
156}
157
158enum gpio_result dal_gpio_get_pin_info(
159	const struct gpio *gpio,
160	struct gpio_pin_info *pin_info)
161{
162	return gpio->service->translate.funcs->id_to_offset(
163		gpio->id, gpio->en, pin_info) ?
164		GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
165}
166
167enum sync_source dal_gpio_get_sync_source(
168	const struct gpio *gpio)
169{
170	switch (gpio->id) {
171	case GPIO_ID_GENERIC:
172		switch (gpio->en) {
173		case GPIO_GENERIC_A:
174			return SYNC_SOURCE_IO_GENERIC_A;
175		case GPIO_GENERIC_B:
176			return SYNC_SOURCE_IO_GENERIC_B;
177		case GPIO_GENERIC_C:
178			return SYNC_SOURCE_IO_GENERIC_C;
179		case GPIO_GENERIC_D:
180			return SYNC_SOURCE_IO_GENERIC_D;
181		case GPIO_GENERIC_E:
182			return SYNC_SOURCE_IO_GENERIC_E;
183		case GPIO_GENERIC_F:
184			return SYNC_SOURCE_IO_GENERIC_F;
185		default:
186			return SYNC_SOURCE_NONE;
187		}
188	break;
189	case GPIO_ID_SYNC:
190		switch (gpio->en) {
191		case GPIO_SYNC_HSYNC_A:
192			return SYNC_SOURCE_IO_HSYNC_A;
193		case GPIO_SYNC_VSYNC_A:
194			return SYNC_SOURCE_IO_VSYNC_A;
195		case GPIO_SYNC_HSYNC_B:
196			return SYNC_SOURCE_IO_HSYNC_B;
197		case GPIO_SYNC_VSYNC_B:
198			return SYNC_SOURCE_IO_VSYNC_B;
199		default:
200			return SYNC_SOURCE_NONE;
201		}
202	break;
203	case GPIO_ID_HPD:
204		switch (gpio->en) {
205		case GPIO_HPD_1:
206			return SYNC_SOURCE_IO_HPD1;
207		case GPIO_HPD_2:
208			return SYNC_SOURCE_IO_HPD2;
209		default:
210			return SYNC_SOURCE_NONE;
211		}
212	break;
213	case GPIO_ID_GSL:
214		switch (gpio->en) {
215		case GPIO_GSL_GENLOCK_CLOCK:
216			return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
217		case GPIO_GSL_GENLOCK_VSYNC:
218			return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
219		case GPIO_GSL_SWAPLOCK_A:
220			return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
221		case GPIO_GSL_SWAPLOCK_B:
222			return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
223		default:
224			return SYNC_SOURCE_NONE;
225		}
226	break;
227	default:
228		return SYNC_SOURCE_NONE;
229	}
230}
231
232enum gpio_pin_output_state dal_gpio_get_output_state(
233	const struct gpio *gpio)
234{
235	return gpio->output_state;
236}
237
238struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)
239{
240	return gpio->hw_container.ddc;
241}
242
243struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)
244{
245	return gpio->hw_container.hpd;
246}
247
248struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)
249{
250	return gpio->hw_container.generic;
251}
252
253void dal_gpio_close(
254	struct gpio *gpio)
255{
256	if (!gpio)
257		return;
258
259	dal_gpio_service_close(gpio->service, &gpio->pin);
260
261	gpio->mode = GPIO_MODE_UNKNOWN;
262}
263
264/*
265 * @brief
266 * Creation and destruction
267 */
268
269struct gpio *dal_gpio_create(
270	struct gpio_service *service,
271	enum gpio_id id,
272	uint32_t en,
273	enum gpio_pin_output_state output_state)
274{
275	struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);
276
277	if (!gpio) {
278		ASSERT_CRITICAL(false);
279		return NULL;
280	}
281
282	gpio->service = service;
283	gpio->pin = NULL;
284	gpio->id = id;
285	gpio->en = en;
286	gpio->mode = GPIO_MODE_UNKNOWN;
287	gpio->output_state = output_state;
288
289	//initialize hw_container union based on id
290	switch (gpio->id) {
291	case GPIO_ID_DDC_DATA:
292		gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
293		break;
294	case GPIO_ID_DDC_CLOCK:
295		gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
296		break;
297	case GPIO_ID_GENERIC:
298		gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en);
299		break;
300	case GPIO_ID_HPD:
301		gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en);
302		break;
303	// TODO: currently gpio for sync and gsl does not get created, might need it later
304	case GPIO_ID_SYNC:
305		break;
306	case GPIO_ID_GSL:
307		break;
308	default:
309		ASSERT_CRITICAL(false);
310		gpio->pin = NULL;
311	}
312
313	return gpio;
314}
315
316void dal_gpio_destroy(
317	struct gpio **gpio)
318{
319	if (!gpio || !*gpio) {
320		ASSERT_CRITICAL(false);
321		return;
322	}
323
324	dal_gpio_close(*gpio);
325
326	switch ((*gpio)->id) {
327	case GPIO_ID_DDC_DATA:
328		kfree((*gpio)->hw_container.ddc);
329		(*gpio)->hw_container.ddc = NULL;
330		break;
331	case GPIO_ID_DDC_CLOCK:
332		//TODO: might want to change it to init_ddc_clock
333		kfree((*gpio)->hw_container.ddc);
334		(*gpio)->hw_container.ddc = NULL;
335		break;
336	case GPIO_ID_GENERIC:
337		kfree((*gpio)->hw_container.generic);
338		(*gpio)->hw_container.generic = NULL;
339		break;
340	case GPIO_ID_HPD:
341		kfree((*gpio)->hw_container.hpd);
342		(*gpio)->hw_container.hpd = NULL;
343		break;
344	// TODO: currently gpio for sync and gsl does not get created, might need it later
345	case GPIO_ID_SYNC:
346		break;
347	case GPIO_ID_GSL:
348		break;
349	default:
350		break;
351	}
352
353	kfree(*gpio);
354
355	*gpio = NULL;
356}
v5.14.15
  1/*
  2 * Copyright 2012-15 Advanced Micro Devices, Inc.
  3 *
  4 * Permission is hereby granted, free of charge, to any person obtaining a
  5 * copy of this software and associated documentation files (the "Software"),
  6 * to deal in the Software without restriction, including without limitation
  7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8 * and/or sell copies of the Software, and to permit persons to whom the
  9 * Software is furnished to do so, subject to the following conditions:
 10 *
 11 * The above copyright notice and this permission notice shall be included in
 12 * all copies or substantial portions of the Software.
 13 *
 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 20 * OTHER DEALINGS IN THE SOFTWARE.
 21 *
 22 * Authors: AMD
 23 *
 24 */
 25
 26/*
 27 * Pre-requisites: headers required by header of this unit
 28 */
 29
 30#include <linux/slab.h>
 31
 32#include "dm_services.h"
 33
 34#include "include/gpio_interface.h"
 35#include "include/gpio_service_interface.h"
 36#include "hw_gpio.h"
 37#include "hw_translate.h"
 38#include "hw_factory.h"
 39#include "gpio_service.h"
 40
 41/*
 42 * Post-requisites: headers required by this unit
 43 */
 44
 45/*
 46 * This unit
 47 */
 48
 49/*
 50 * @brief
 51 * Public API
 52 */
 53
 54enum gpio_result dal_gpio_open(
 55	struct gpio *gpio,
 56	enum gpio_mode mode)
 57{
 58	return dal_gpio_open_ex(gpio, mode);
 59}
 60
 61enum gpio_result dal_gpio_open_ex(
 62	struct gpio *gpio,
 63	enum gpio_mode mode)
 64{
 65	if (gpio->pin) {
 66		BREAK_TO_DEBUGGER();
 67		return GPIO_RESULT_ALREADY_OPENED;
 68	}
 69
 70	// No action if allocation failed during gpio construct
 71	if (!gpio->hw_container.ddc) {
 72		BREAK_TO_DEBUGGER();
 73		return GPIO_RESULT_NON_SPECIFIC_ERROR;
 74	}
 75	gpio->mode = mode;
 76
 77	return dal_gpio_service_open(gpio);
 78}
 79
 80enum gpio_result dal_gpio_get_value(
 81	const struct gpio *gpio,
 82	uint32_t *value)
 83{
 84	if (!gpio->pin) {
 85		BREAK_TO_DEBUGGER();
 86		return GPIO_RESULT_NULL_HANDLE;
 87	}
 88
 89	return gpio->pin->funcs->get_value(gpio->pin, value);
 90}
 91
 92enum gpio_result dal_gpio_set_value(
 93	const struct gpio *gpio,
 94	uint32_t value)
 95{
 96	if (!gpio->pin) {
 97		BREAK_TO_DEBUGGER();
 98		return GPIO_RESULT_NULL_HANDLE;
 99	}
100
101	return gpio->pin->funcs->set_value(gpio->pin, value);
102}
103
104enum gpio_mode dal_gpio_get_mode(
105	const struct gpio *gpio)
106{
107	return gpio->mode;
108}
109
110enum gpio_result dal_gpio_lock_pin(
111	struct gpio *gpio)
112{
113	return dal_gpio_service_lock(gpio->service, gpio->id, gpio->en);
114}
115
116enum gpio_result dal_gpio_unlock_pin(
117	struct gpio *gpio)
118{
119	return dal_gpio_service_unlock(gpio->service, gpio->id, gpio->en);
120}
121
122enum gpio_result dal_gpio_change_mode(
123	struct gpio *gpio,
124	enum gpio_mode mode)
125{
126	if (!gpio->pin) {
127		BREAK_TO_DEBUGGER();
128		return GPIO_RESULT_NULL_HANDLE;
129	}
130
131	return gpio->pin->funcs->change_mode(gpio->pin, mode);
132}
133
134enum gpio_id dal_gpio_get_id(
135	const struct gpio *gpio)
136{
137	return gpio->id;
138}
139
140uint32_t dal_gpio_get_enum(
141	const struct gpio *gpio)
142{
143	return gpio->en;
144}
145
146enum gpio_result dal_gpio_set_config(
147	struct gpio *gpio,
148	const struct gpio_config_data *config_data)
149{
150	if (!gpio->pin) {
151		BREAK_TO_DEBUGGER();
152		return GPIO_RESULT_NULL_HANDLE;
153	}
154
155	return gpio->pin->funcs->set_config(gpio->pin, config_data);
156}
157
158enum gpio_result dal_gpio_get_pin_info(
159	const struct gpio *gpio,
160	struct gpio_pin_info *pin_info)
161{
162	return gpio->service->translate.funcs->id_to_offset(
163		gpio->id, gpio->en, pin_info) ?
164		GPIO_RESULT_OK : GPIO_RESULT_INVALID_DATA;
165}
166
167enum sync_source dal_gpio_get_sync_source(
168	const struct gpio *gpio)
169{
170	switch (gpio->id) {
171	case GPIO_ID_GENERIC:
172		switch (gpio->en) {
173		case GPIO_GENERIC_A:
174			return SYNC_SOURCE_IO_GENERIC_A;
175		case GPIO_GENERIC_B:
176			return SYNC_SOURCE_IO_GENERIC_B;
177		case GPIO_GENERIC_C:
178			return SYNC_SOURCE_IO_GENERIC_C;
179		case GPIO_GENERIC_D:
180			return SYNC_SOURCE_IO_GENERIC_D;
181		case GPIO_GENERIC_E:
182			return SYNC_SOURCE_IO_GENERIC_E;
183		case GPIO_GENERIC_F:
184			return SYNC_SOURCE_IO_GENERIC_F;
185		default:
186			return SYNC_SOURCE_NONE;
187		}
188	break;
189	case GPIO_ID_SYNC:
190		switch (gpio->en) {
191		case GPIO_SYNC_HSYNC_A:
192			return SYNC_SOURCE_IO_HSYNC_A;
193		case GPIO_SYNC_VSYNC_A:
194			return SYNC_SOURCE_IO_VSYNC_A;
195		case GPIO_SYNC_HSYNC_B:
196			return SYNC_SOURCE_IO_HSYNC_B;
197		case GPIO_SYNC_VSYNC_B:
198			return SYNC_SOURCE_IO_VSYNC_B;
199		default:
200			return SYNC_SOURCE_NONE;
201		}
202	break;
203	case GPIO_ID_HPD:
204		switch (gpio->en) {
205		case GPIO_HPD_1:
206			return SYNC_SOURCE_IO_HPD1;
207		case GPIO_HPD_2:
208			return SYNC_SOURCE_IO_HPD2;
209		default:
210			return SYNC_SOURCE_NONE;
211		}
212	break;
213	case GPIO_ID_GSL:
214		switch (gpio->en) {
215		case GPIO_GSL_GENLOCK_CLOCK:
216			return SYNC_SOURCE_GSL_IO_GENLOCK_CLOCK;
217		case GPIO_GSL_GENLOCK_VSYNC:
218			return SYNC_SOURCE_GSL_IO_GENLOCK_VSYNC;
219		case GPIO_GSL_SWAPLOCK_A:
220			return SYNC_SOURCE_GSL_IO_SWAPLOCK_A;
221		case GPIO_GSL_SWAPLOCK_B:
222			return SYNC_SOURCE_GSL_IO_SWAPLOCK_B;
223		default:
224			return SYNC_SOURCE_NONE;
225		}
226	break;
227	default:
228		return SYNC_SOURCE_NONE;
229	}
230}
231
232enum gpio_pin_output_state dal_gpio_get_output_state(
233	const struct gpio *gpio)
234{
235	return gpio->output_state;
236}
237
238struct hw_ddc *dal_gpio_get_ddc(struct gpio *gpio)
239{
240	return gpio->hw_container.ddc;
241}
242
243struct hw_hpd *dal_gpio_get_hpd(struct gpio *gpio)
244{
245	return gpio->hw_container.hpd;
246}
247
248struct hw_generic *dal_gpio_get_generic(struct gpio *gpio)
249{
250	return gpio->hw_container.generic;
251}
252
253void dal_gpio_close(
254	struct gpio *gpio)
255{
256	if (!gpio)
257		return;
258
259	dal_gpio_service_close(gpio->service, &gpio->pin);
260
261	gpio->mode = GPIO_MODE_UNKNOWN;
262}
263
264/*
265 * @brief
266 * Creation and destruction
267 */
268
269struct gpio *dal_gpio_create(
270	struct gpio_service *service,
271	enum gpio_id id,
272	uint32_t en,
273	enum gpio_pin_output_state output_state)
274{
275	struct gpio *gpio = kzalloc(sizeof(struct gpio), GFP_KERNEL);
276
277	if (!gpio) {
278		ASSERT_CRITICAL(false);
279		return NULL;
280	}
281
282	gpio->service = service;
283	gpio->pin = NULL;
284	gpio->id = id;
285	gpio->en = en;
286	gpio->mode = GPIO_MODE_UNKNOWN;
287	gpio->output_state = output_state;
288
289	//initialize hw_container union based on id
290	switch (gpio->id) {
291	case GPIO_ID_DDC_DATA:
292		gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
293		break;
294	case GPIO_ID_DDC_CLOCK:
295		gpio->service->factory.funcs->init_ddc_data(&gpio->hw_container.ddc, service->ctx, id, en);
296		break;
297	case GPIO_ID_GENERIC:
298		gpio->service->factory.funcs->init_generic(&gpio->hw_container.generic, service->ctx, id, en);
299		break;
300	case GPIO_ID_HPD:
301		gpio->service->factory.funcs->init_hpd(&gpio->hw_container.hpd, service->ctx, id, en);
302		break;
303	// TODO: currently gpio for sync and gsl does not get created, might need it later
304	case GPIO_ID_SYNC:
305		break;
306	case GPIO_ID_GSL:
307		break;
308	default:
309		ASSERT_CRITICAL(false);
310		gpio->pin = NULL;
311	}
312
313	return gpio;
314}
315
316void dal_gpio_destroy(
317	struct gpio **gpio)
318{
319	if (!gpio || !*gpio) {
320		ASSERT_CRITICAL(false);
321		return;
322	}
 
 
323
324	switch ((*gpio)->id) {
325	case GPIO_ID_DDC_DATA:
326		kfree((*gpio)->hw_container.ddc);
327		(*gpio)->hw_container.ddc = NULL;
328		break;
329	case GPIO_ID_DDC_CLOCK:
330		//TODO: might want to change it to init_ddc_clock
331		kfree((*gpio)->hw_container.ddc);
332		(*gpio)->hw_container.ddc = NULL;
333		break;
334	case GPIO_ID_GENERIC:
335		kfree((*gpio)->hw_container.generic);
336		(*gpio)->hw_container.generic = NULL;
337		break;
338	case GPIO_ID_HPD:
339		kfree((*gpio)->hw_container.hpd);
340		(*gpio)->hw_container.hpd = NULL;
341		break;
342	// TODO: currently gpio for sync and gsl does not get created, might need it later
343	case GPIO_ID_SYNC:
344		break;
345	case GPIO_ID_GSL:
346		break;
347	default:
348		break;
349	}
350
351	kfree(*gpio);
352
353	*gpio = NULL;
354}