18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * linux/drivers/pcmcia/sa1100_neponset.c
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Neponset PCMCIA specific routines
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci#include <linux/module.h>
88c2ecf20Sopenharmony_ci#include <linux/kernel.h>
98c2ecf20Sopenharmony_ci#include <linux/device.h>
108c2ecf20Sopenharmony_ci#include <linux/errno.h>
118c2ecf20Sopenharmony_ci#include <linux/init.h>
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <asm/mach-types.h>
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include "sa1111_generic.h"
168c2ecf20Sopenharmony_ci#include "max1600.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci/*
198c2ecf20Sopenharmony_ci * Neponset uses the Maxim MAX1600, with the following connections:
208c2ecf20Sopenharmony_ci *
218c2ecf20Sopenharmony_ci *   MAX1600      Neponset
228c2ecf20Sopenharmony_ci *
238c2ecf20Sopenharmony_ci *    A0VCC        SA-1111 GPIO A<1>
248c2ecf20Sopenharmony_ci *    A1VCC        SA-1111 GPIO A<0>
258c2ecf20Sopenharmony_ci *    A0VPP        CPLD NCR A0VPP
268c2ecf20Sopenharmony_ci *    A1VPP        CPLD NCR A1VPP
278c2ecf20Sopenharmony_ci *    B0VCC        SA-1111 GPIO A<2>
288c2ecf20Sopenharmony_ci *    B1VCC        SA-1111 GPIO A<3>
298c2ecf20Sopenharmony_ci *    B0VPP        ground (slot B is CF)
308c2ecf20Sopenharmony_ci *    B1VPP        ground (slot B is CF)
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci *     VX          VCC (5V)
338c2ecf20Sopenharmony_ci *     VY          VCC3_3 (3.3V)
348c2ecf20Sopenharmony_ci *     12INA       12V
358c2ecf20Sopenharmony_ci *     12INB       ground (slot B is CF)
368c2ecf20Sopenharmony_ci *
378c2ecf20Sopenharmony_ci * The MAX1600 CODE pin is tied to ground, placing the device in
388c2ecf20Sopenharmony_ci * "Standard Intel code" mode. Refer to the Maxim data sheet for
398c2ecf20Sopenharmony_ci * the corresponding truth table.
408c2ecf20Sopenharmony_ci */
418c2ecf20Sopenharmony_cistatic int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	struct max1600 *m;
448c2ecf20Sopenharmony_ci	int ret;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	ret = max1600_init(skt->socket.dev.parent, &m,
478c2ecf20Sopenharmony_ci			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
488c2ecf20Sopenharmony_ci			   MAX1600_CODE_LOW);
498c2ecf20Sopenharmony_ci	if (ret == 0)
508c2ecf20Sopenharmony_ci		skt->driver_data = m;
518c2ecf20Sopenharmony_ci
528c2ecf20Sopenharmony_ci	return ret;
538c2ecf20Sopenharmony_ci}
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_cistatic int
568c2ecf20Sopenharmony_cineponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
578c2ecf20Sopenharmony_ci{
588c2ecf20Sopenharmony_ci	struct max1600 *m = skt->driver_data;
598c2ecf20Sopenharmony_ci	int ret;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	ret = sa1111_pcmcia_configure_socket(skt, state);
628c2ecf20Sopenharmony_ci	if (ret == 0)
638c2ecf20Sopenharmony_ci		ret = max1600_configure(m, state->Vcc, state->Vpp);
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	return ret;
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_cistatic struct pcmcia_low_level neponset_pcmcia_ops = {
698c2ecf20Sopenharmony_ci	.owner			= THIS_MODULE,
708c2ecf20Sopenharmony_ci	.hw_init		= neponset_pcmcia_hw_init,
718c2ecf20Sopenharmony_ci	.configure_socket	= neponset_pcmcia_configure_socket,
728c2ecf20Sopenharmony_ci	.first			= 0,
738c2ecf20Sopenharmony_ci	.nr			= 2,
748c2ecf20Sopenharmony_ci};
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciint pcmcia_neponset_init(struct sa1111_dev *sadev)
778c2ecf20Sopenharmony_ci{
788c2ecf20Sopenharmony_ci	sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
798c2ecf20Sopenharmony_ci	return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
808c2ecf20Sopenharmony_ci				 sa11xx_drv_pcmcia_add_one);
818c2ecf20Sopenharmony_ci}
82